tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / sd / qa / unit / import-tests.cxx
blob41beb185e0c64dd2a91e6a3e443de93714fa62c5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <config_poppler.h>
12 #include "sdmodeltestbase.hxx"
13 #include <tools/color.hxx>
15 #include <editeng/eeitem.hxx>
16 #include <editeng/editobj.hxx>
17 #include <editeng/ulspitem.hxx>
18 #include <editeng/fhgtitem.hxx>
19 #include <editeng/escapementitem.hxx>
20 #include <editeng/colritem.hxx>
21 #include <editeng/numitem.hxx>
23 #include <svx/svdoashp.hxx>
24 #include <svx/svdogrp.hxx>
25 #include <svx/svdoole2.hxx>
26 #include <svx/svdotable.hxx>
27 #include <svx/xfillit0.hxx>
28 #include <svx/xflclit.hxx>
29 #include <svx/xlineit0.hxx>
30 #include <svx/xlnclit.hxx>
31 #include <svx/xlnwtit.hxx>
32 #include <svx/sdasitm.hxx>
33 #include <svx/sdmetitm.hxx>
34 #include <animations/animationnodehelper.hxx>
35 #include <sax/tools/converter.hxx>
37 #include <com/sun/star/awt/Gradient.hpp>
38 #include <com/sun/star/awt/FontWeight.hpp>
39 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
40 #include <com/sun/star/document/XEventsSupplier.hpp>
41 #include <com/sun/star/presentation/ClickAction.hpp>
42 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
43 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
44 #include <com/sun/star/animations/XAnimate.hpp>
45 #include <com/sun/star/chart/XChartDocument.hpp>
46 #include <com/sun/star/chart2/XChartDocument.hpp>
47 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
48 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
49 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
50 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
51 #include <com/sun/star/table/BorderLineStyle.hpp>
52 #include <com/sun/star/table/BorderLine2.hpp>
53 #include <com/sun/star/style/ParagraphAdjust.hpp>
54 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
55 #include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
56 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
57 #include <com/sun/star/drawing/ConnectorType.hpp>
58 #include <com/sun/star/drawing/RectanglePoint.hpp>
60 #include <stlpool.hxx>
61 #include <undo/undomanager.hxx>
63 #include <unotools/syslocaleoptions.hxx>
64 #include <comphelper/scopeguard.hxx>
65 #include <comphelper/sequenceashashmap.hxx>
66 #include <comphelper/lok.hxx>
67 #include <svx/svdograf.hxx>
68 #include <vcl/filter/PDFiumLibrary.hxx>
70 using namespace ::com::sun::star;
72 namespace com::sun::star::uno
74 template <class T>
75 static std::ostream& operator<<(std::ostream& rStrm, const uno::Reference<T>& xRef)
77 rStrm << xRef.get();
78 return rStrm;
82 /// Impress import filters tests.
83 class SdImportTest : public SdModelTestBase
85 public:
86 SdImportTest()
87 : SdModelTestBase(u"/sd/qa/unit/data/"_ustr)
92 /** Test document against a reference XML dump of shapes.
94 If you want to update one of these tests, or add a new one, set the nUpdateMe
95 to the index of the test, and the dump XML's will be created (or rewritten)
96 instead of checking. Use with care - when the test is failing, first find out
97 why, instead of just updating .xml's blindly.
99 Example: Let's say you are adding a test called fdoABCD.pptx. You'll place it
100 to the data/ subdirectory, and will add an entry to aFilesToCompare below,
101 the 3rd parameter is for export test - can be -1 (don't export), "impress8", "MS PowerPoint 97" or "Impress Office Open XML"
102 like:
104 { "fdoABCD.pptx", "xml/fdoABCD_", "Impress Office Open XML" },
106 and will count the index in the aFilesToCompare structure (1st is 0, 2nd is 1,
107 etc.) Temporarily you'll set nUpdateMe to this index (instead of -1), and run
109 make sd
111 This will generate the sd/qa/unit/data/xml/fdoABCD_*.xml for you. Now you
112 will change nUpdateMe back to -1, and commit your fdoABCD.pptx test, the
113 xml/fdoABCD_*.xml dumps, and the aFilesToCompare addition in one commit.
115 As the last step, you will revert your fix and do 'make sd' again, to check
116 that without your fix, the unit test breaks. Then clean up, and push :-)
118 NOTE: This approach is suitable only for tests of fixes that actually change
119 the layout - best to check by reverting your fix locally after having added
120 the test, and re-running; it should break.
122 CPPUNIT_TEST_FIXTURE(SdImportTest, testDocumentLayout)
124 static const struct
126 std::u16string_view sInput, sDump;
127 OUString sExportType;
128 } aFilesToCompare[]
129 = { { u"odp/shapes-test.odp", u"xml/shapes-test_page", u""_ustr },
130 { u"fdo47434.pptx", u"xml/fdo47434_", u""_ustr },
131 { u"n758621.ppt", u"xml/n758621_", u""_ustr },
132 { u"fdo64586.ppt", u"xml/fdo64586_", u""_ustr },
134 // needed to adapt this, the border parameter is no longer
135 // exported with MCGRs due to oox neither needing nor
136 // supporting it with now freely definable gradients
137 { u"n819614.pptx", u"xml/n819614_", u""_ustr },
139 { u"n820786.pptx", u"xml/n820786_", u""_ustr },
140 { u"n762695.pptx", u"xml/n762695_", u""_ustr },
141 { u"n593612.pptx", u"xml/n593612_", u""_ustr },
142 { u"fdo71434.pptx", u"xml/fdo71434_", u""_ustr },
143 { u"n902652.pptx", u"xml/n902652_", u""_ustr },
144 { u"tdf90403.pptx", u"xml/tdf90403_", u""_ustr },
145 { u"tdf90338.odp", u"xml/tdf90338_", u"Impress Office Open XML"_ustr },
146 { u"tdf92001.odp", u"xml/tdf92001_", u"Impress Office Open XML"_ustr },
147 // GCC -mfpmath=387 rounding issues in lclPushMarkerProperties
148 // (oox/source/drawingml/lineproperties.cxx); see mail sub-thread starting at
149 // <https://lists.freedesktop.org/archives/libreoffice/2016-September/
150 // 075211.html> "Re: Test File: sc/qa/unit/data/functions/fods/chiinv.fods:
151 // fails with Assertion" for how "-mfpmath=sse -msse2" would fix that:
152 #if !(defined LINUX && defined X86)
153 { u"tdf100491.pptx", u"xml/tdf100491_", u""_ustr },
154 #endif
155 { u"tdf109317.pptx", u"xml/tdf109317_", u"impress8"_ustr },
156 // { u"pptx/n828390.pptx", u"pptx/xml/n828390_", "Impress Office Open XML" }, // Example
159 for (int i = 0; i < static_cast<int>(SAL_N_ELEMENTS(aFilesToCompare)); ++i)
161 int const nUpdateMe
162 = -1; // index of test we want to update; supposedly only when the test is created
164 loadFromFile(aFilesToCompare[i].sInput);
165 if (!aFilesToCompare[i].sExportType.isEmpty())
166 saveAndReload(aFilesToCompare[i].sExportType);
167 uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent,
168 uno::UNO_QUERY_THROW);
169 uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
170 CPPUNIT_ASSERT(xDrawPages.is());
172 sal_Int32 nLength = xDrawPages->getCount();
173 for (sal_Int32 j = 0; j < nLength; ++j)
175 uno::Reference<drawing::XDrawPage> xDrawPage;
176 uno::Any aAny = xDrawPages->getByIndex(j);
177 aAny >>= xDrawPage;
178 uno::Reference<drawing::XShapes> xShapes(xDrawPage, uno::UNO_QUERY_THROW);
179 OUString aString = XShapeDumper::dump(xShapes);
181 OString aFileName
182 = OUStringToOString(createFileURL(aFilesToCompare[i].sDump), RTL_TEXTENCODING_UTF8)
183 + OString::number(j) + ".xml";
185 if (nUpdateMe == i) // index was wrong here
187 // had to adapt this, std::ofstream annot write to an URL but needs a
188 // filesystem path. Seems as if no one had to adapt any of the cases
189 // for some years :-/
190 OUString sTempFilePath;
191 osl::FileBase::getSystemPathFromFileURL(OUString::fromUtf8(aFileName),
192 sTempFilePath);
193 std::ofstream aStream(sTempFilePath.toUtf8().getStr(),
194 std::ofstream::out | std::ofstream::binary);
195 aStream << aString;
196 aStream.close();
198 else
200 doXMLDiff(aFileName.getStr(),
201 OUStringToOString(aString, RTL_TEXTENCODING_UTF8).getStr(),
202 static_cast<int>(aString.getLength()),
203 OUStringToOString(createFileURL(u"tolerance.xml"), RTL_TEXTENCODING_UTF8)
204 .getStr());
210 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf157216)
212 createSdImpressDoc("pptx/tdf157216.pptx");
213 uno::Reference<beans::XPropertySet> xFlowchartShape(getShapeFromPage(0, 0));
214 uno::Sequence<beans::PropertyValue> aProps;
215 xFlowchartShape->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aProps;
217 uno::Sequence<beans::PropertyValue> aPathProps;
218 for (beans::PropertyValue const& rProp : aProps)
220 if (rProp.Name == "Path")
221 aPathProps = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
224 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
225 for (beans::PropertyValue const& rProp : aPathProps)
227 if (rProp.Name == "GluePoints")
229 seqGluePoints
230 = rProp.Value.get<uno::Sequence<drawing::EnhancedCustomShapeParameterPair>>();
234 sal_Int32 nCountGluePoints = seqGluePoints.getLength();
235 // The Flowchart: Punched Tape has 4 glue points.
236 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), nCountGluePoints);
239 CPPUNIT_TEST_FIXTURE(SdImportTest, testTableStyle)
241 createSdImpressDoc("pptx/tdf156718.pptx");
242 const SdrPage* pPage = GetPage(1);
244 sdr::table::SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
245 CPPUNIT_ASSERT(pTableObj);
247 uno::Reference<table::XCellRange> xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
248 uno::Reference<beans::XPropertySet> xCellPropSet;
249 uno::Reference<beans::XPropertySet> xRunPropSet;
250 uno::Reference<text::XTextRange> xParagraph;
251 uno::Reference<text::XTextRange> xRun;
252 table::BorderLine2 aBorderLine;
253 Color nFillColor, nCharColor;
254 float nFontWeight;
256 xCellPropSet.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
257 xParagraph.set(getParagraphFromShape(0, xCellPropSet));
258 xRun.set(getRunFromParagraph(0, xParagraph));
259 xRunPropSet.set(xRun, uno::UNO_QUERY_THROW);
260 xRunPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
261 xRunPropSet->getPropertyValue(u"CharWeight"_ustr) >>= nFontWeight;
262 xCellPropSet->getPropertyValue(u"BottomBorder"_ustr) >>= aBorderLine;
263 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nCharColor);
264 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, nFontWeight);
265 CPPUNIT_ASSERT_EQUAL_MESSAGE("The bottom border is missing!", true, aBorderLine.LineWidth > 0);
267 xCellPropSet.set(xTable->getCellByPosition(1, 0), uno::UNO_QUERY_THROW);
268 xParagraph.set(getParagraphFromShape(0, xCellPropSet));
269 xRun.set(getRunFromParagraph(0, xParagraph));
270 xRunPropSet.set(xRun, uno::UNO_QUERY_THROW);
271 xRunPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
272 xRunPropSet->getPropertyValue(u"CharWeight"_ustr) >>= nFontWeight;
273 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nCharColor);
274 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, nFontWeight);
276 xCellPropSet.set(xTable->getCellByPosition(2, 0), uno::UNO_QUERY_THROW);
277 xParagraph.set(getParagraphFromShape(0, xCellPropSet));
278 xRun.set(getRunFromParagraph(0, xParagraph));
279 xRunPropSet.set(xRun, uno::UNO_QUERY_THROW);
280 xRunPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
281 xRunPropSet->getPropertyValue(u"CharWeight"_ustr) >>= nFontWeight;
282 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nCharColor);
283 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, nFontWeight);
285 xCellPropSet.set(xTable->getCellByPosition(0, 1), uno::UNO_QUERY_THROW);
286 xParagraph.set(getParagraphFromShape(0, xCellPropSet));
287 xRun.set(getRunFromParagraph(0, xParagraph));
288 xRunPropSet.set(xRun, uno::UNO_QUERY_THROW);
289 xRunPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
290 xRunPropSet->getPropertyValue(u"CharWeight"_ustr) >>= nFontWeight;
291 xCellPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
292 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nCharColor);
293 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, nFontWeight);
294 CPPUNIT_ASSERT_EQUAL(Color(0x5b9bd5), nFillColor);
296 xCellPropSet.set(xTable->getCellByPosition(2, 1), uno::UNO_QUERY_THROW);
297 xParagraph.set(getParagraphFromShape(0, xCellPropSet));
298 xRun.set(getRunFromParagraph(0, xParagraph));
299 xRunPropSet.set(xRun, uno::UNO_QUERY_THROW);
300 xRunPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
301 xRunPropSet->getPropertyValue(u"CharWeight"_ustr) >>= nFontWeight;
302 xCellPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
303 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nCharColor);
304 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, nFontWeight);
305 CPPUNIT_ASSERT_EQUAL(Color(0x5b9bd5), nFillColor);
308 CPPUNIT_TEST_FIXTURE(SdImportTest, testFreeformShapeGluePoints)
310 createSdImpressDoc("pptx/tdf156829.pptx");
311 uno::Reference<beans::XPropertySet> xFreeformShape(getShapeFromPage(0, 0));
312 uno::Sequence<beans::PropertyValue> aProps;
313 xFreeformShape->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aProps;
315 uno::Sequence<beans::PropertyValue> aPathProps;
316 for (beans::PropertyValue const& rProp : aProps)
318 if (rProp.Name == "Path")
319 aPathProps = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
322 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
323 for (beans::PropertyValue const& rProp : aPathProps)
325 if (rProp.Name == "GluePoints")
327 seqGluePoints
328 = rProp.Value.get<uno::Sequence<drawing::EnhancedCustomShapeParameterPair>>();
332 sal_Int32 nCountGluePoints = seqGluePoints.getLength();
333 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nCountGluePoints);
336 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf154363)
338 sal_Int32 nGlueId;
339 createSdImpressDoc("pptx/tdf154363.pptx");
341 uno::Reference<beans::XPropertySet> xConnector1(getShapeFromPage(1, 0), uno::UNO_SET_THROW);
342 uno::Reference<beans::XPropertySet> xConnector2(getShapeFromPage(3, 0), uno::UNO_SET_THROW);
343 nGlueId = xConnector1->getPropertyValue(u"StartGluePointIndex"_ustr).get<sal_Int32>();
344 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nGlueId);
345 nGlueId = xConnector2->getPropertyValue(u"EndGluePointIndex"_ustr).get<sal_Int32>();
346 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nGlueId);
349 saveAndReload(u"Impress MS PowerPoint 2007 XML"_ustr);
351 uno::Reference<beans::XPropertySet> xConnector1(getShapeFromPage(1, 0), uno::UNO_SET_THROW);
352 uno::Reference<beans::XPropertySet> xConnector2(getShapeFromPage(3, 0), uno::UNO_SET_THROW);
353 nGlueId = xConnector1->getPropertyValue(u"StartGluePointIndex"_ustr).get<sal_Int32>();
354 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nGlueId);
355 nGlueId = xConnector2->getPropertyValue(u"EndGluePointIndex"_ustr).get<sal_Int32>();
356 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nGlueId);
360 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf153466)
362 createSdImpressDoc("pptx/tdf153466.pptx");
364 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
365 uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
366 uno::Reference<beans::XPropertySet> xPageSet(xPage, uno::UNO_QUERY_THROW);
367 uno::Reference<beans::XPropertySet> xBackground(
368 xPageSet->getPropertyValue(u"Background"_ustr).get<uno::Reference<beans::XPropertySet>>());
370 css::drawing::RectanglePoint aRectanglePoint;
371 xBackground->getPropertyValue(u"FillBitmapRectanglePoint"_ustr) >>= aRectanglePoint;
372 CPPUNIT_ASSERT_EQUAL(drawing::RectanglePoint::RectanglePoint_RIGHT_BOTTOM, aRectanglePoint);
374 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0), uno::UNO_SET_THROW);
375 xShape->getPropertyValue(u"FillBitmapRectanglePoint"_ustr) >>= aRectanglePoint;
376 CPPUNIT_ASSERT_EQUAL(drawing::RectanglePoint::RectanglePoint_LEFT_MIDDLE, aRectanglePoint);
379 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf152434)
381 createSdImpressDoc("pptx/tdf152434.pptx");
383 SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
384 CPPUNIT_ASSERT(pXImpressDocument);
385 SdDrawDocument* pDoc = pXImpressDocument->GetDoc();
386 const SdrPage* pPage = pDoc->GetPage(1);
387 CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
390 CPPUNIT_TEST_FIXTURE(SdImportTest, testConnectors)
392 createSdImpressDoc("pptx/connectors.pptx");
394 sal_Int32 aEdgeValue[] = { -1167, -1167, -1591, 1476, 1356, -1357, 1604, -1540,
395 607, 1296, -1638, -1060, 2402, 3313, -1834, 333 };
397 sal_Int32 nCount = 0;
398 for (size_t i = 0; i < 18; i++)
400 uno::Reference<beans::XPropertySet> xConnector(getShapeFromPage(i, 0));
401 bool bConnector
402 = xConnector->getPropertySetInfo()->hasPropertyByName(u"EdgeLine1Delta"_ustr);
403 if (bConnector)
405 sal_Int32 nEdgeLine
406 = xConnector->getPropertyValue(u"EdgeLine1Delta"_ustr).get<sal_Int32>();
407 CPPUNIT_ASSERT_EQUAL(aEdgeValue[nCount], nEdgeLine);
408 nCount++;
413 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf153036_resizedConnectorL)
415 createSdImpressDoc("pptx/tdf153036_resizedConnectorL.pptx");
417 // TODO: If you are working on improvement related to connectors import, then
418 // expect this unit test to fail.
419 // This is a "L" shape, imported as a special "Z" shape that looks like a "L" shape.
420 uno::Reference<beans::XPropertySet> xConnector(getShapeFromPage(1, 0));
421 CPPUNIT_ASSERT(xConnector->getPropertySetInfo()->hasPropertyByName(u"EdgeLine1Delta"_ustr));
423 sal_Int32 nEdgeLine = xConnector->getPropertyValue(u"EdgeLine1Delta"_ustr).get<sal_Int32>();
424 CPPUNIT_ASSERT_EQUAL(sal_Int32(-3243), nEdgeLine);
427 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf150719)
429 createSdImpressDoc("pptx/tdf150719.pptx");
431 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
432 uno::Reference<text::XTextRange> const xParagraph(getParagraphFromShape(0, xShape));
433 uno::Reference<text::XTextRange> xRun(getRunFromParagraph(1, xParagraph));
434 uno::Reference<beans::XPropertySet> xPropSet1(xRun, uno::UNO_QUERY_THROW);
435 sal_Int16 nUnderline;
436 xPropSet1->getPropertyValue(u"CharUnderline"_ustr) >>= nUnderline;
437 CPPUNIT_ASSERT_EQUAL_MESSAGE("The underline is missing!", sal_Int16(1), nUnderline);
440 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf149314)
442 createSdImpressDoc("pptx/tdf149314.pptx");
444 OUString aURL;
445 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 1));
447 uno::Reference<text::XTextRange> const xParagraph1(getParagraphFromShape(0, xShape));
448 uno::Reference<text::XTextRange> xRun1(getRunFromParagraph(0, xParagraph1));
449 uno::Reference<beans::XPropertySet> xPropSet1(xRun1, uno::UNO_QUERY_THROW);
450 uno::Reference<text::XTextField> xField1;
451 xPropSet1->getPropertyValue(u"TextField"_ustr) >>= xField1;
452 xPropSet1.set(xField1, uno::UNO_QUERY);
453 xPropSet1->getPropertyValue(u"URL"_ustr) >>= aURL;
454 CPPUNIT_ASSERT_EQUAL_MESSAGE("URLs don't match", u"#Slide 1"_ustr, aURL);
456 uno::Reference<text::XTextRange> const xParagraph2(getParagraphFromShape(1, xShape));
457 uno::Reference<text::XTextRange> xRun2(getRunFromParagraph(0, xParagraph2));
458 uno::Reference<beans::XPropertySet> xPropSet2(xRun2, uno::UNO_QUERY_THROW);
459 uno::Reference<text::XTextField> xField2;
460 xPropSet2->getPropertyValue(u"TextField"_ustr) >>= xField2;
461 xPropSet2.set(xField2, uno::UNO_QUERY);
462 xPropSet2->getPropertyValue(u"URL"_ustr) >>= aURL;
463 CPPUNIT_ASSERT_EQUAL_MESSAGE("URLs don't match", u"#Slide 3"_ustr, aURL);
466 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf149124)
468 createSdImpressDoc("pptx/tdf149124.pptx");
470 uno::Reference<container::XIndexAccess> xGroupShape(getShapeFromPage(0, 0),
471 uno::UNO_QUERY_THROW);
472 uno::Reference<beans::XPropertySet> xStandardConnector(xGroupShape->getByIndex(2),
473 uno::UNO_QUERY_THROW);
475 sal_Int32 nStartGlueId
476 = xStandardConnector->getPropertyValue(u"StartGluePointIndex"_ustr).get<sal_Int32>();
477 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), nStartGlueId);
478 sal_Int32 nEndGlueId
479 = xStandardConnector->getPropertyValue(u"EndGluePointIndex"_ustr).get<sal_Int32>();
480 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nEndGlueId);
483 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf148965)
485 // Set the system user interface to Hungarian
486 SvtSysLocaleOptions aOptions;
487 OUString sUIConfigString = aOptions.GetLanguageTag().getBcp47();
488 aOptions.SetUILocaleConfigString(u"hu-HU"_ustr);
489 aOptions.Commit();
490 comphelper::ScopeGuard g([&aOptions, &sUIConfigString] {
491 aOptions.SetUILocaleConfigString(sUIConfigString);
492 aOptions.Commit();
495 createSdImpressDoc("pptx/tdf148965.pptx");
497 uno::Reference<beans::XPropertySet> xShape1(getShapeFromPage(0, 1));
498 uno::Reference<document::XEventsSupplier> xEventsSupplier1(xShape1, uno::UNO_QUERY);
499 uno::Reference<container::XNameAccess> xEvents1(xEventsSupplier1->getEvents());
500 uno::Sequence<beans::PropertyValue> props1;
501 xEvents1->getByName(u"OnClick"_ustr) >>= props1;
502 comphelper::SequenceAsHashMap map1(props1);
503 auto iter1(map1.find(u"Bookmark"_ustr));
504 CPPUNIT_ASSERT_EQUAL(u"page1"_ustr, iter1->second.get<OUString>());
506 uno::Reference<beans::XPropertySet> xShape2(getShapeFromPage(1, 1));
507 uno::Reference<document::XEventsSupplier> xEventsSupplier2(xShape2, uno::UNO_QUERY);
508 uno::Reference<container::XNameAccess> xEvents2(xEventsSupplier2->getEvents());
509 uno::Sequence<beans::PropertyValue> props2;
510 xEvents2->getByName(u"OnClick"_ustr) >>= props2;
511 comphelper::SequenceAsHashMap map2(props2);
512 auto iter2(map2.find(u"Bookmark"_ustr));
513 CPPUNIT_ASSERT_EQUAL(u"page3"_ustr, iter2->second.get<OUString>());
516 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf89449)
518 createSdImpressDoc("pptx/tdf89449.pptx");
520 sal_Int32 nStartGlueId;
521 sal_Int32 nEndGlueId;
522 css::drawing::ConnectorType aConnectorType;
524 uno::Reference<beans::XPropertySet> xCurvedConnector(getShapeFromPage(3, 0));
525 xCurvedConnector->getPropertyValue(u"EdgeKind"_ustr) >>= aConnectorType;
526 CPPUNIT_ASSERT_EQUAL(drawing::ConnectorType::ConnectorType_CURVE, aConnectorType);
527 nStartGlueId = xCurvedConnector->getPropertyValue(u"StartGluePointIndex"_ustr).get<sal_Int32>();
528 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nStartGlueId);
529 nEndGlueId = xCurvedConnector->getPropertyValue(u"EndGluePointIndex"_ustr).get<sal_Int32>();
530 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nEndGlueId);
532 uno::Reference<beans::XPropertySet> xStraightConnector(getShapeFromPage(4, 0));
533 xStraightConnector->getPropertyValue(u"EdgeKind"_ustr) >>= aConnectorType;
534 CPPUNIT_ASSERT_EQUAL(drawing::ConnectorType::ConnectorType_LINE, aConnectorType);
535 nStartGlueId
536 = xStraightConnector->getPropertyValue(u"StartGluePointIndex"_ustr).get<sal_Int32>();
537 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nStartGlueId);
538 nEndGlueId = xStraightConnector->getPropertyValue(u"EndGluePointIndex"_ustr).get<sal_Int32>();
539 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), nEndGlueId);
541 uno::Reference<beans::XPropertySet> xStandardConnector(getShapeFromPage(5, 0));
542 xStandardConnector->getPropertyValue(u"EdgeKind"_ustr) >>= aConnectorType;
543 CPPUNIT_ASSERT_EQUAL(drawing::ConnectorType::ConnectorType_STANDARD, aConnectorType);
544 nStartGlueId
545 = xStandardConnector->getPropertyValue(u"StartGluePointIndex"_ustr).get<sal_Int32>();
546 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), nStartGlueId);
547 nEndGlueId = xStandardConnector->getPropertyValue(u"EndGluePointIndex"_ustr).get<sal_Int32>();
548 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), nEndGlueId);
551 CPPUNIT_TEST_FIXTURE(SdImportTest, testGluePointLeavingDirections)
553 createSdImpressDoc("pptx/glue_point_leaving_directions.pptx");
554 uno::Reference<beans::XPropertySet> xEllipseShape(getShapeFromPage(0, 0));
555 uno::Sequence<beans::PropertyValue> aProps;
556 xEllipseShape->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aProps;
558 uno::Sequence<beans::PropertyValue> aPathProps;
559 for (beans::PropertyValue const& rProp : aProps)
561 if (rProp.Name == "Path")
562 aPathProps = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
565 uno::Sequence<double> seqGluePointLeavingDirections;
566 for (beans::PropertyValue const& rProp : aPathProps)
568 if (rProp.Name == "GluePointLeavingDirections")
570 rProp.Value >>= seqGluePointLeavingDirections;
574 sal_Int32 nCountGluePointLeavingDirections = seqGluePointLeavingDirections.getLength();
575 // The ellipse has 8 glue point leaving directions
576 CPPUNIT_ASSERT_EQUAL(sal_Int32(8), nCountGluePointLeavingDirections);
579 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf147459)
581 createSdImpressDoc("pptx/tdf147459.pptx");
582 uno::Reference<beans::XPropertySet> xTriangleShape(getShapeFromPage(0, 0));
583 uno::Sequence<beans::PropertyValue> aProps;
584 xTriangleShape->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aProps;
586 uno::Sequence<beans::PropertyValue> aPathProps;
587 for (beans::PropertyValue const& rProp : aProps)
589 if (rProp.Name == "Path")
590 aPathProps = rProp.Value.get<uno::Sequence<beans::PropertyValue>>();
593 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
594 for (beans::PropertyValue const& rProp : aPathProps)
596 if (rProp.Name == "GluePoints")
598 seqGluePoints
599 = rProp.Value.get<uno::Sequence<drawing::EnhancedCustomShapeParameterPair>>();
603 sal_Int32 nCountGluePoints = seqGluePoints.getLength();
604 // The triangle has 6 glue points.
605 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), nCountGluePoints);
608 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf146223)
610 createSdImpressDoc("pptx/tdf146223.pptx");
612 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
614 uno::Reference<drawing::XDrawPage> xPage1(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
615 uno::Reference<beans::XPropertySet> xSet(xPage1, uno::UNO_QUERY_THROW);
617 bool bBackgroundObjectsVisible;
618 xSet->getPropertyValue(u"IsBackgroundObjectsVisible"_ustr) >>= bBackgroundObjectsVisible;
619 CPPUNIT_ASSERT_EQUAL(false, bBackgroundObjectsVisible);
622 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf144918)
624 createSdImpressDoc("pptx/tdf144918.pptx");
626 uno::Reference<beans::XPropertySet> xShape1(getShapeFromPage(0, 1));
627 uno::Reference<document::XEventsSupplier> xEventsSupplier1(xShape1, uno::UNO_QUERY);
628 uno::Reference<container::XNameAccess> xEvents1(xEventsSupplier1->getEvents());
629 uno::Sequence<beans::PropertyValue> props1;
630 xEvents1->getByName(u"OnClick"_ustr) >>= props1;
631 comphelper::SequenceAsHashMap map1(props1);
632 auto iter1(map1.find(u"Bookmark"_ustr));
633 CPPUNIT_ASSERT_EQUAL(u"First slide"_ustr, iter1->second.get<OUString>());
635 uno::Reference<beans::XPropertySet> xShape2(getShapeFromPage(1, 1));
636 uno::Reference<document::XEventsSupplier> xEventsSupplier2(xShape2, uno::UNO_QUERY);
637 uno::Reference<container::XNameAccess> xEvents2(xEventsSupplier2->getEvents());
638 uno::Sequence<beans::PropertyValue> props2;
639 xEvents2->getByName(u"OnClick"_ustr) >>= props2;
640 comphelper::SequenceAsHashMap map2(props2);
641 auto iter2(map2.find(u"Bookmark"_ustr));
642 CPPUNIT_ASSERT_EQUAL(u"Third slide"_ustr, iter2->second.get<OUString>());
645 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf144917)
647 createSdImpressDoc("pptx/tdf144917.pptx");
649 uno::Reference<container::XIndexAccess> xGroupShape(getShapeFromPage(0, 0),
650 uno::UNO_QUERY_THROW);
651 uno::Reference<beans::XPropertySet> xShape(xGroupShape->getByIndex(1), uno::UNO_QUERY_THROW);
652 uno::Reference<document::XEventsSupplier> xEventsSupplier(xShape, uno::UNO_QUERY);
653 uno::Reference<container::XNameAccess> xEvents(xEventsSupplier->getEvents());
654 uno::Sequence<beans::PropertyValue> props;
655 xEvents->getByName(u"OnClick"_ustr) >>= props;
656 comphelper::SequenceAsHashMap map(props);
657 auto iter(map.find(u"Bookmark"_ustr));
658 CPPUNIT_ASSERT_EQUAL(u"http://www.example.com/"_ustr, iter->second.get<OUString>());
661 CPPUNIT_TEST_FIXTURE(SdImportTest, testHyperlinkOnImage)
663 createSdImpressDoc("pptx/hyperlinkOnImage.pptx");
665 uno::Reference<beans::XPropertySet> xShape1(getShapeFromPage(1, 0));
666 uno::Reference<document::XEventsSupplier> xEventsSupplier1(xShape1, uno::UNO_QUERY);
667 uno::Reference<container::XNameAccess> xEvents1(xEventsSupplier1->getEvents());
668 uno::Sequence<beans::PropertyValue> props1;
669 xEvents1->getByName(u"OnClick"_ustr) >>= props1;
670 comphelper::SequenceAsHashMap map1(props1);
671 auto iter1(map1.find(u"ClickAction"_ustr));
672 CPPUNIT_ASSERT_EQUAL(css::presentation::ClickAction_LASTPAGE,
673 iter1->second.get<css::presentation::ClickAction>());
675 uno::Reference<beans::XPropertySet> xShape2(getShapeFromPage(1, 1));
676 uno::Reference<document::XEventsSupplier> xEventsSupplier2(xShape2, uno::UNO_QUERY);
677 uno::Reference<container::XNameAccess> xEvents2(xEventsSupplier2->getEvents());
678 uno::Sequence<beans::PropertyValue> props2;
679 xEvents2->getByName(u"OnClick"_ustr) >>= props2;
680 comphelper::SequenceAsHashMap map2(props2);
681 auto iter2(map2.find(u"ClickAction"_ustr));
682 CPPUNIT_ASSERT_EQUAL(css::presentation::ClickAction_NONE,
683 iter2->second.get<css::presentation::ClickAction>());
686 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf142645)
688 createSdImpressDoc("pptx/tdf142645.pptx");
689 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
691 uno::Reference<drawing::XDrawPage> xPage1(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
692 uno::Reference<container::XNamed> xNamed1(xPage1, uno::UNO_QUERY_THROW);
693 CPPUNIT_ASSERT_EQUAL(u"Hello"_ustr, xNamed1->getName());
696 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf141704)
698 createSdImpressDoc("pptx/tdf141704.pptx");
700 for (sal_Int32 i = 0; i < 7; i++)
702 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(1, i));
703 uno::Reference<document::XEventsSupplier> xEventsSupplier(xShape, uno::UNO_QUERY);
704 uno::Reference<container::XNameAccess> xEvents(xEventsSupplier->getEvents());
706 uno::Sequence<beans::PropertyValue> props;
707 xEvents->getByName(u"OnClick"_ustr) >>= props;
708 comphelper::SequenceAsHashMap map(props);
709 auto iter(map.find(u"ClickAction"_ustr));
710 switch (i)
712 case 0:
713 CPPUNIT_ASSERT_EQUAL(css::presentation::ClickAction_LASTPAGE,
714 iter->second.get<css::presentation::ClickAction>());
715 break;
716 case 1:
717 CPPUNIT_ASSERT_EQUAL(css::presentation::ClickAction_NEXTPAGE,
718 iter->second.get<css::presentation::ClickAction>());
719 break;
720 case 2:
721 CPPUNIT_ASSERT_EQUAL(css::presentation::ClickAction_PREVPAGE,
722 iter->second.get<css::presentation::ClickAction>());
723 break;
724 case 3:
726 auto iter1(map.find(u"Bookmark"_ustr));
727 CPPUNIT_ASSERT_EQUAL(u"http://www.example.com/"_ustr,
728 iter1->second.get<OUString>());
730 break;
731 case 4:
733 auto iter2(map.find(u"Bookmark"_ustr));
734 CPPUNIT_ASSERT_EQUAL(u"End Show"_ustr, iter2->second.get<OUString>());
736 break;
737 case 5:
738 CPPUNIT_ASSERT_EQUAL(css::presentation::ClickAction_STOPPRESENTATION,
739 iter->second.get<css::presentation::ClickAction>());
740 break;
741 case 6:
742 CPPUNIT_ASSERT_EQUAL(css::presentation::ClickAction_FIRSTPAGE,
743 iter->second.get<css::presentation::ClickAction>());
744 break;
745 default:
746 break;
751 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf142915)
753 createSdImpressDoc("pptx/tdf142915.pptx");
755 uno::Reference<presentation::XPresentationSupplier> xPresentationSupplier(mxComponent,
756 uno::UNO_QUERY_THROW);
757 uno::Reference<beans::XPropertySet> xPresentationProps(xPresentationSupplier->getPresentation(),
758 uno::UNO_QUERY_THROW);
760 bool bChangeManually = xPresentationProps->getPropertyValue(u"IsAutomatic"_ustr).get<bool>();
762 CPPUNIT_ASSERT_EQUAL(true, bChangeManually);
765 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf142913)
767 createSdImpressDoc("pptx/tdf142913.pptx");
769 uno::Reference<presentation::XPresentationSupplier> xPresentationSupplier(mxComponent,
770 uno::UNO_QUERY_THROW);
771 uno::Reference<beans::XPropertySet> xPresentationProps(xPresentationSupplier->getPresentation(),
772 uno::UNO_QUERY_THROW);
774 OUString sFirstPage = xPresentationProps->getPropertyValue(u"FirstPage"_ustr).get<OUString>();
776 CPPUNIT_ASSERT_EQUAL(u"Second"_ustr, sFirstPage);
779 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf142590)
781 createSdImpressDoc("pptx/tdf142590.pptx");
783 uno::Reference<presentation::XPresentationSupplier> xPresentationSupplier(mxComponent,
784 uno::UNO_QUERY_THROW);
785 uno::Reference<beans::XPropertySet> xPresentationProps(xPresentationSupplier->getPresentation(),
786 uno::UNO_QUERY_THROW);
787 const OUString sCustomShowId
788 = xPresentationProps->getPropertyValue(u"CustomShow"_ustr).get<OUString>();
790 CPPUNIT_ASSERT(!sCustomShowId.isEmpty());
793 CPPUNIT_TEST_FIXTURE(SdImportTest, testCustomSlideShow)
795 createSdImpressDoc("pptx/tdf131390.pptx");
797 css::uno::Reference<css::presentation::XCustomPresentationSupplier> aXCPSup(
798 mxComponent, css::uno::UNO_QUERY);
799 css::uno::Reference<css::container::XNameContainer> aXCont(aXCPSup->getCustomPresentations());
800 const css::uno::Sequence<OUString> aNameSeq(aXCont->getElementNames());
802 // In the document, there are two custom presentations.
803 CPPUNIT_ASSERT_EQUAL(sal_uInt32(2), aNameSeq.size());
806 CPPUNIT_TEST_FIXTURE(SdImportTest, testInternalHyperlink)
808 createSdImpressDoc("pptx/tdf65724.pptx");
810 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(1, 0));
812 // Get first paragraph
813 uno::Reference<text::XTextRange> const xParagraph(getParagraphFromShape(0, xShape));
815 // first chunk of text
816 uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
817 uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW);
819 uno::Reference<text::XTextField> xField;
820 xPropSet->getPropertyValue(u"TextField"_ustr) >>= xField;
821 CPPUNIT_ASSERT_MESSAGE("The text field is missing!", xField.is());
823 xPropSet.set(xField, uno::UNO_QUERY);
824 OUString aURL;
825 xPropSet->getPropertyValue(u"URL"_ustr) >>= aURL;
826 CPPUNIT_ASSERT_EQUAL_MESSAGE("URLs don't match", u"#Slide2"_ustr, aURL);
829 CPPUNIT_TEST_FIXTURE(SdImportTest, testHyperlinkColor)
831 createSdImpressDoc("pptx/tdf137367.pptx");
833 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
835 // Get first paragraph of the text
836 uno::Reference<text::XTextRange> const xParagraph1(getParagraphFromShape(0, xShape));
837 // Get second paragraph of the text
838 uno::Reference<text::XTextRange> const xParagraph2(getParagraphFromShape(1, xShape));
839 // Get third paragraph of the text
840 uno::Reference<text::XTextRange> const xParagraph3(getParagraphFromShape(2, xShape));
842 // Get run of the first paragraph
843 uno::Reference<text::XTextRange> xRun1(getRunFromParagraph(0, xParagraph1));
844 uno::Reference<beans::XPropertySet> xPropSet1(xRun1, uno::UNO_QUERY_THROW);
845 Color nCharColorBlue;
846 xPropSet1->getPropertyValue(u"CharColor"_ustr) >>= nCharColorBlue;
848 // Get run of the second paragraph
849 uno::Reference<text::XTextRange> xRun2(getRunFromParagraph(1, xParagraph2));
850 uno::Reference<beans::XPropertySet> xPropSet2(xRun2, uno::UNO_QUERY_THROW);
851 Color nCharColorRed;
852 xPropSet2->getPropertyValue(u"CharColor"_ustr) >>= nCharColorRed;
854 // Get run of the third paragraph
855 uno::Reference<text::XTextRange> xRun3(getRunFromParagraph(2, xParagraph3));
856 uno::Reference<beans::XPropertySet> xPropSet3(xRun3, uno::UNO_QUERY_THROW);
857 Color nCharColorGreen;
858 xPropSet3->getPropertyValue(u"CharColor"_ustr) >>= nCharColorGreen;
860 // Hyperlink colors should be blue, red, green.
861 CPPUNIT_ASSERT_EQUAL(Color(0x4472c4), nCharColorBlue);
862 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, nCharColorRed);
863 CPPUNIT_ASSERT_EQUAL(Color(0x548235), nCharColorGreen);
866 CPPUNIT_TEST_FIXTURE(SdImportTest, testSmoketest)
868 createSdImpressDoc("smoketest.pptx");
870 SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
871 CPPUNIT_ASSERT(pXImpressDocument);
872 SdDrawDocument* pDoc = pXImpressDocument->GetDoc();
874 // cf. SdrModel svx/svdmodel.hxx ...
876 CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong page count", static_cast<sal_uInt16>(3),
877 pDoc->GetPageCount());
879 const SdrPage* pPage = pDoc->GetPage(1);
880 CPPUNIT_ASSERT_MESSAGE("no page", pPage != nullptr);
882 CPPUNIT_ASSERT_MESSAGE("changed", !pDoc->IsChanged());
885 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf131269)
887 createSdImpressDoc("tdf131269.ppt");
889 SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
890 CPPUNIT_ASSERT(pXImpressDocument);
891 SdDrawDocument* pDoc = pXImpressDocument->GetDoc();
893 // Without the fix in place, this test would have failed with
894 // - Expected: 115
895 // - Actual : 3
896 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(115), pDoc->GetPageCount());
899 CPPUNIT_TEST_FIXTURE(SdImportTest, testN759180)
901 createSdImpressDoc("n759180.pptx");
903 const SdrPage* pPage = GetPage(1);
905 // Get the object
906 SdrObject* pObj = pPage->GetObj(0);
907 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
908 CPPUNIT_ASSERT(pTxtObj);
909 std::vector<EECharAttrib> rLst;
910 const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
911 const SvxULSpaceItem* pULSpace = aEdit.GetParaAttribs(0).GetItem(EE_PARA_ULSPACE);
912 CPPUNIT_ASSERT(pULSpace);
913 CPPUNIT_ASSERT_EQUAL_MESSAGE("Para bottom spacing is wrong!", static_cast<sal_uInt16>(0),
914 pULSpace->GetLower());
915 aEdit.GetCharAttribs(1, rLst);
916 auto it = std::find_if(rLst.rbegin(), rLst.rend(), [](const EECharAttrib& rCharAttr) {
917 return dynamic_cast<const SvxFontHeightItem*>(rCharAttr.pAttr) != nullptr;
919 if (it != rLst.rend())
921 const SvxFontHeightItem* pFontHeight = dynamic_cast<const SvxFontHeightItem*>((*it).pAttr);
922 // nStart == 9
923 // font height = 5 => 5*2540/72
924 CPPUNIT_ASSERT_EQUAL_MESSAGE("Font height is wrong", static_cast<sal_uInt32>(176),
925 pFontHeight->GetHeight());
929 CPPUNIT_TEST_FIXTURE(SdImportTest, testN862510_1)
931 createSdImpressDoc("pptx/n862510_1.pptx");
933 const SdrPage* pPage = GetPage(1);
935 std::vector<EECharAttrib> rLst;
936 SdrObject* pObj = pPage->GetObj(0);
937 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
938 CPPUNIT_ASSERT(pTxtObj);
939 const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
940 aEdit.GetCharAttribs(0, rLst);
941 for (std::vector<EECharAttrib>::reverse_iterator it = rLst.rbegin(); it != rLst.rend();
942 ++it)
944 const SvxEscapementItem* pFontEscapement
945 = dynamic_cast<const SvxEscapementItem*>((*it).pAttr);
946 CPPUNIT_ASSERT_MESSAGE(
947 "Baseline attribute not handled properly",
948 !(pFontEscapement && pFontEscapement->GetProportionalHeight() != 100));
953 CPPUNIT_TEST_FIXTURE(SdImportTest, testN862510_2)
955 createSdImpressDoc("pptx/n862510_2.pptx");
957 const SdrPage* pPage = GetPage(1);
959 CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
960 SdrObjGroup* pGrpObj = dynamic_cast<SdrObjGroup*>(pPage->GetObj(0));
961 CPPUNIT_ASSERT(pGrpObj);
962 SdrObjCustomShape* pObj
963 = dynamic_cast<SdrObjCustomShape*>(pGrpObj->GetSubList()->GetObj(1));
964 CPPUNIT_ASSERT(pObj);
965 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong Text Rotation!", 90.0,
966 pObj->GetExtraTextRotation(false));
970 CPPUNIT_TEST_FIXTURE(SdImportTest, testN862510_4)
972 createSdImpressDoc("pptx/n862510_4.pptx");
974 const SdrPage* pPage = GetPage(1);
976 std::vector<EECharAttrib> rLst;
977 SdrObject* pObj = pPage->GetObj(0);
978 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
979 CPPUNIT_ASSERT(pTxtObj);
980 const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
981 aEdit.GetCharAttribs(0, rLst);
982 for (std::vector<EECharAttrib>::reverse_iterator it = rLst.rbegin(); it != rLst.rend();
983 ++it)
985 const SvxColorItem* pC = dynamic_cast<const SvxColorItem*>((*it).pAttr);
986 CPPUNIT_ASSERT_MESSAGE("gradfill for text color not handled!",
987 !(pC && pC->GetValue() == COL_BLACK));
992 CPPUNIT_TEST_FIXTURE(SdImportTest, testN828390_2)
994 createSdImpressDoc("pptx/n828390_2.pptx");
995 const SdrPage* pPage = GetPage(1);
997 SdrObject* pObj = pPage->GetObj(0);
998 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
999 CPPUNIT_ASSERT(pTxtObj);
1000 const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
1001 CPPUNIT_ASSERT_EQUAL(u"Linux "_ustr, aEdit.GetText(0));
1002 CPPUNIT_ASSERT_EQUAL(u"Standard Platform"_ustr, aEdit.GetText(1));
1005 CPPUNIT_TEST_FIXTURE(SdImportTest, testN828390_3)
1007 createSdImpressDoc("pptx/n828390_3.pptx");
1008 const SdrPage* pPage = GetPage(1);
1010 SdrObject* pObj = pPage->GetObj(0);
1011 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
1012 CPPUNIT_ASSERT(pTxtObj);
1013 const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
1014 std::vector<EECharAttrib> rLst;
1015 aEdit.GetCharAttribs(1, rLst);
1016 bool bPassed = std::none_of(rLst.rbegin(), rLst.rend(), [](const EECharAttrib& rCharAttr) {
1017 const SvxEscapementItem* pFontEscapement
1018 = dynamic_cast<const SvxEscapementItem*>(rCharAttr.pAttr);
1019 return pFontEscapement && (pFontEscapement->GetEsc() != 0);
1021 CPPUNIT_ASSERT_MESSAGE("CharEscapment not imported properly", bPassed);
1024 CPPUNIT_TEST_FIXTURE(SdImportTest, testMasterPageStyleParent)
1026 createSdImpressDoc("odp/masterpage_style_parent.odp");
1027 SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
1028 CPPUNIT_ASSERT(pXImpressDocument);
1029 SdDrawDocument* pDoc = pXImpressDocument->GetDoc();
1031 SdStyleSheetPool* const pPool(pDoc->GetSdStyleSheetPool());
1033 int parents(0);
1034 SfxStyleSheetIterator iter(pPool, SfxStyleFamily::Page);
1035 for (SfxStyleSheetBase* pStyle = iter.First(); pStyle; pStyle = iter.Next())
1037 OUString const name(pStyle->GetName());
1038 OUString const parent(pStyle->GetParent());
1039 if (!parent.isEmpty())
1041 ++parents;
1042 // check that parent exists
1043 SfxStyleSheetBase* const pParentStyle(pPool->Find(parent, SfxStyleFamily::Page));
1044 CPPUNIT_ASSERT(pParentStyle);
1045 CPPUNIT_ASSERT_EQUAL(pParentStyle->GetName(), parent);
1046 // check that parent has the same master page as pStyle
1047 CPPUNIT_ASSERT(parent.indexOf(SD_LT_SEPARATOR) != -1);
1048 CPPUNIT_ASSERT(name.indexOf(SD_LT_SEPARATOR) != -1);
1049 CPPUNIT_ASSERT_EQUAL(parent.copy(0, parent.indexOf(SD_LT_SEPARATOR)),
1050 name.copy(0, name.indexOf(SD_LT_SEPARATOR)));
1053 // check that there are actually parents...
1054 CPPUNIT_ASSERT_EQUAL(16, parents);
1057 CPPUNIT_TEST_FIXTURE(SdImportTest, testGradientAngle)
1059 createSdDrawDoc("odg/gradient-angle.fodg");
1061 uno::Reference<lang::XMultiServiceFactory> const xDoc(mxComponent, uno::UNO_QUERY);
1063 awt::Gradient gradient;
1064 uno::Reference<container::XNameAccess> const xGradients(
1065 xDoc->createInstance(u"com.sun.star.drawing.GradientTable"_ustr), uno::UNO_QUERY);
1067 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 38"_ustr) >>= gradient);
1068 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), gradient.Angle); // was: 3600
1070 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 10"_ustr) >>= gradient);
1071 CPPUNIT_ASSERT_EQUAL(sal_Int16(270), gradient.Angle); // 27deg
1073 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 11"_ustr) >>= gradient);
1074 CPPUNIT_ASSERT_EQUAL(sal_Int16(1146), gradient.Angle); // 2rad = 114.591deg
1076 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 12"_ustr) >>= gradient);
1077 CPPUNIT_ASSERT_EQUAL(sal_Int16(900), gradient.Angle); // 100grad
1079 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 13"_ustr) >>= gradient);
1080 CPPUNIT_ASSERT_EQUAL(sal_Int16(3599), gradient.Angle); // -1
1082 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 14"_ustr) >>= gradient);
1083 CPPUNIT_ASSERT_EQUAL(sal_Int16(3027), gradient.Angle); // -1rad = -57.295deg -> 302.704deg
1085 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 15"_ustr) >>= gradient);
1086 CPPUNIT_ASSERT_EQUAL(sal_Int16(300), gradient.Angle); // 3900
1088 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 16"_ustr) >>= gradient);
1089 CPPUNIT_ASSERT_EQUAL(sal_Int16(105), gradient.Angle); // 10.5deg
1091 CPPUNIT_ASSERT(xGradients->getByName(u"Gradient 17"_ustr) >>= gradient);
1092 CPPUNIT_ASSERT_EQUAL(sal_Int16(1800), gradient.Angle); // \pi rad
1094 uno::Reference<container::XNameAccess> const xTranspGradients(
1095 xDoc->createInstance(u"com.sun.star.drawing.TransparencyGradientTable"_ustr),
1096 uno::UNO_QUERY);
1098 CPPUNIT_ASSERT(xTranspGradients->getByName(u"Transparency 2"_ustr) >>= gradient);
1099 CPPUNIT_ASSERT_EQUAL(sal_Int16(10), gradient.Angle); // 1
1101 CPPUNIT_ASSERT(xTranspGradients->getByName(u"Transparency 1"_ustr) >>= gradient);
1102 CPPUNIT_ASSERT_EQUAL(sal_Int16(900), gradient.Angle); // 90deg
1104 CPPUNIT_ASSERT(xTranspGradients->getByName(u"Transparency 3"_ustr) >>= gradient);
1105 CPPUNIT_ASSERT_EQUAL(sal_Int16(573), gradient.Angle); // 1.0rad = 57.295deg
1107 CPPUNIT_ASSERT(xTranspGradients->getByName(u"Transparency 4"_ustr) >>= gradient);
1108 CPPUNIT_ASSERT_EQUAL(sal_Int16(1800), gradient.Angle); // 1000grad = 900deg -> 180deg
1111 CPPUNIT_TEST_FIXTURE(SdImportTest, testN778859)
1113 createSdImpressDoc("pptx/n778859.pptx");
1115 const SdrPage* pPage = GetPage(1);
1117 // Get the object
1118 SdrObject* pObj = pPage->GetObj(1);
1119 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
1120 CPPUNIT_ASSERT_MESSAGE("no text object", pTxtObj != nullptr);
1121 CPPUNIT_ASSERT(!pTxtObj->IsAutoFit());
1125 CPPUNIT_TEST_FIXTURE(SdImportTest, testFdo68594)
1127 createSdImpressDoc("ppt/fdo68594.ppt");
1129 const SdrPage* pPage = &(GetPage(1)->TRG_GetMasterPage());
1130 SdrObject* pObj = pPage->GetObj(1);
1131 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
1132 CPPUNIT_ASSERT_MESSAGE("no text object", pTxtObj != nullptr);
1133 const SvxColorItem* pC = &pTxtObj->GetMergedItem(EE_CHAR_COLOR);
1134 CPPUNIT_ASSERT_MESSAGE("no color item", pC != nullptr);
1135 // Color should be black
1136 CPPUNIT_ASSERT_EQUAL_MESSAGE("Placeholder color mismatch", COL_BLACK, pC->GetValue());
1139 CPPUNIT_TEST_FIXTURE(SdImportTest, testPlaceholderPriority)
1141 createSdImpressDoc("ppt/placeholder-priority.pptx");
1143 const SdrPage* pPage = GetPage(1);
1144 CPPUNIT_ASSERT_EQUAL_MESSAGE("Missing placeholder", sal_uInt32(2),
1145 sal_uInt32(pPage->GetObjCount()));
1147 tools::Rectangle pObj1Rect(9100, 3500, 29619, 4038);
1148 SdrObject* pObj1 = pPage->GetObj(0);
1149 CPPUNIT_ASSERT_EQUAL_MESSAGE("Placeholder position is wrong, check the placeholder priority",
1150 pObj1Rect, pObj1->GetCurrentBoundRect());
1152 tools::Rectangle pObj2Rect(9102, 8643, 29619, 12642);
1153 SdrObject* pObj2 = pPage->GetObj(1);
1154 CPPUNIT_ASSERT_EQUAL_MESSAGE("Placeholder position is wrong, check the placeholder priority",
1155 pObj2Rect, pObj2->GetCurrentBoundRect());
1157 // If the placeholder positions are wrong, please check placeholder priority in Placeholders class.
1160 CPPUNIT_TEST_FIXTURE(SdImportTest, testFdo72998)
1162 createSdImpressDoc("pptx/cshapes.pptx");
1164 const SdrPage* pPage = GetPage(1);
1166 SdrObjCustomShape* pObj = dynamic_cast<SdrObjCustomShape*>(pPage->GetObj(2));
1167 CPPUNIT_ASSERT(pObj);
1168 const SdrCustomShapeGeometryItem& rGeometryItem
1169 = pObj->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY);
1170 const css::uno::Any* pViewBox = rGeometryItem.GetPropertyValueByName(u"ViewBox"_ustr);
1171 CPPUNIT_ASSERT_MESSAGE("Missing ViewBox", pViewBox);
1172 css::awt::Rectangle aViewBox;
1173 CPPUNIT_ASSERT((*pViewBox >>= aViewBox));
1174 CPPUNIT_ASSERT_MESSAGE("Width should be zero - for forcing scale to 1", !aViewBox.Width);
1175 CPPUNIT_ASSERT_MESSAGE("Height should be zero - for forcing scale to 1", !aViewBox.Height);
1179 CPPUNIT_TEST_FIXTURE(SdImportTest, testFdo77027)
1181 createSdImpressDoc("odp/fdo77027.odp");
1183 const SdrPage* pPage = GetPage(1);
1185 SdrOle2Obj* const pObj = dynamic_cast<SdrOle2Obj*>(pPage->GetObj(0));
1186 CPPUNIT_ASSERT(pObj);
1188 // check that the fill style/color was actually imported
1189 const XFillStyleItem& rStyleItem = pObj->GetMergedItem(XATTR_FILLSTYLE);
1190 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1191 const XFillColorItem& rColorItem = pObj->GetMergedItem(XATTR_FILLCOLOR);
1192 CPPUNIT_ASSERT_EQUAL(Color(0xff6600), rColorItem.GetColorValue());
1196 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf97808)
1198 createSdImpressDoc("tdf97808.fodp");
1200 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
1201 uno::UNO_QUERY);
1202 uno::Reference<container::XNameAccess> xStyleFamilies
1203 = xStyleFamiliesSupplier->getStyleFamilies();
1204 uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(u"graphics"_ustr),
1205 uno::UNO_QUERY);
1206 uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName(u"objectwithoutfill"_ustr),
1207 uno::UNO_QUERY);
1208 OUString lineend;
1209 CPPUNIT_ASSERT(xStyle->getPropertyValue(u"LineEndName"_ustr) >>= lineend);
1210 CPPUNIT_ASSERT_EQUAL(u"Arrow"_ustr, lineend);
1212 // the draw:marker-end="" did not override the style
1213 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
1214 uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0),
1215 uno::UNO_QUERY_THROW);
1216 uno::Reference<beans::XPropertySet> xLine(xPage->getByIndex(0), uno::UNO_QUERY_THROW);
1217 //uno::Reference<style::XStyle> xParent;
1218 uno::Reference<beans::XPropertySet> xParent;
1219 CPPUNIT_ASSERT(xLine->getPropertyValue(u"Style"_ustr) >>= xParent);
1220 CPPUNIT_ASSERT_EQUAL(xStyle, xParent);
1221 CPPUNIT_ASSERT(xLine->getPropertyValue(u"LineEndName"_ustr) >>= lineend);
1222 CPPUNIT_ASSERT_EQUAL(OUString(), lineend);
1224 CPPUNIT_TEST_FIXTURE(SdImportTest, testFillStyleNone)
1226 createSdDrawDoc("tdf123841.odg");
1228 const SdrPage* pPage = GetPage(1);
1229 const SdrObject* pObj = pPage->GetObj(0);
1230 auto& rFillStyleItem = pObj->GetMergedItem(XATTR_FILLSTYLE);
1231 // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
1232 // 1', i.e. the shape's fill was FillStyle_SOLID, making the text of the shape unreadable.
1233 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, rFillStyleItem.GetValue());
1236 CPPUNIT_TEST_FIXTURE(SdImportTest, testFdo64512)
1238 createSdImpressDoc("fdo64512.odp");
1240 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
1241 CPPUNIT_ASSERT_EQUAL_MESSAGE("not exactly one page", static_cast<sal_Int32>(1),
1242 xDoc->getDrawPages()->getCount());
1244 uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0),
1245 uno::UNO_QUERY_THROW);
1246 CPPUNIT_ASSERT_EQUAL_MESSAGE("not exactly three shapes", static_cast<sal_Int32>(3),
1247 xPage->getCount());
1249 uno::Reference<beans::XPropertySet> xConnectorShape(xPage->getByIndex(2), uno::UNO_QUERY);
1250 CPPUNIT_ASSERT_MESSAGE("no connector shape", xConnectorShape.is());
1252 uno::Reference<beans::XPropertySet> xSvgShape(
1253 xConnectorShape->getPropertyValue(u"StartShape"_ustr), uno::UNO_QUERY);
1254 CPPUNIT_ASSERT_MESSAGE("no start shape", xSvgShape.is());
1256 uno::Reference<beans::XPropertySet> xCustomShape(
1257 xConnectorShape->getPropertyValue(u"EndShape"_ustr), uno::UNO_QUERY);
1258 CPPUNIT_ASSERT_MESSAGE("no end shape", xCustomShape.is());
1260 uno::Reference<animations::XAnimationNodeSupplier> xAnimNodeSupplier(xPage,
1261 uno::UNO_QUERY_THROW);
1262 uno::Reference<animations::XAnimationNode> xRootNode(xAnimNodeSupplier->getAnimationNode());
1263 std::vector<uno::Reference<animations::XAnimationNode>> aAnimVector;
1264 anim::create_deep_vector(xRootNode, aAnimVector);
1265 CPPUNIT_ASSERT_EQUAL_MESSAGE("not 8 animation nodes", static_cast<std::size_t>(8),
1266 aAnimVector.size());
1268 uno::Reference<animations::XAnimate> xNode(aAnimVector[7], uno::UNO_QUERY_THROW);
1269 uno::Reference<drawing::XShape> xTargetShape(xNode->getTarget(), uno::UNO_QUERY_THROW);
1270 CPPUNIT_ASSERT_MESSAGE("inner node not referencing svg shape", xTargetShape != xSvgShape);
1273 // Unit test for importing charts
1274 CPPUNIT_TEST_FIXTURE(SdImportTest, testFdo71075)
1276 double values[] = { 12.0, 13.0, 14.0 };
1277 css::uno::Any aAny;
1279 createSdImpressDoc("fdo71075.odp");
1281 uno::Reference<beans::XPropertySet> xPropSet(getShapeFromPage(0, 0));
1282 aAny = xPropSet->getPropertyValue(u"Model"_ustr);
1283 CPPUNIT_ASSERT_MESSAGE("The shape doesn't have the property", aAny.hasValue());
1285 uno::Reference<chart::XChartDocument> xChartDoc;
1286 aAny >>= xChartDoc;
1287 CPPUNIT_ASSERT_MESSAGE("failed to load chart", xChartDoc.is());
1288 uno::Reference<chart2::XChartDocument> xChart2Doc(xChartDoc, uno::UNO_QUERY);
1289 CPPUNIT_ASSERT_MESSAGE("failed to load chart", xChart2Doc.is());
1291 uno::Reference<chart2::XCoordinateSystemContainer> xBCooSysCnt(xChart2Doc->getFirstDiagram(),
1292 uno::UNO_QUERY);
1293 uno::Sequence<uno::Reference<chart2::XCoordinateSystem>> aCooSysSeq(
1294 xBCooSysCnt->getCoordinateSystems());
1295 uno::Reference<chart2::XChartTypeContainer> xCTCnt(aCooSysSeq[0], uno::UNO_QUERY);
1297 uno::Reference<chart2::XDataSeriesContainer> xDSCnt(xCTCnt->getChartTypes()[0], uno::UNO_QUERY);
1298 CPPUNIT_ASSERT_MESSAGE("failed to load data series", xDSCnt.is());
1299 uno::Sequence<uno::Reference<chart2::XDataSeries>> aSeriesSeq(xDSCnt->getDataSeries());
1300 CPPUNIT_ASSERT_EQUAL_MESSAGE("Invalid Series count", static_cast<sal_Int32>(1),
1301 aSeriesSeq.getLength());
1302 uno::Reference<chart2::data::XDataSource> xSource(aSeriesSeq[0], uno::UNO_QUERY);
1303 uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence>> aSeqCnt(
1304 xSource->getDataSequences());
1305 CPPUNIT_ASSERT_EQUAL_MESSAGE("Invalid Series count", static_cast<sal_Int32>(1),
1306 aSeqCnt.getLength());
1307 uno::Reference<chart2::data::XDataSequence> xValueSeq(aSeqCnt[0]->getValues());
1308 CPPUNIT_ASSERT_EQUAL_MESSAGE("Invalid Data count",
1309 static_cast<sal_Int32>(SAL_N_ELEMENTS(values)),
1310 xValueSeq->getData().getLength());
1311 uno::Reference<chart2::data::XNumericalDataSequence> xNumSeq(xValueSeq, uno::UNO_QUERY);
1312 uno::Sequence<double> aValues(xNumSeq->getNumericalData());
1313 for (sal_Int32 i = 0; i < xValueSeq->getData().getLength(); i++)
1314 CPPUNIT_ASSERT_EQUAL_MESSAGE("Invalid Series count", values[i], aValues[i]);
1317 CPPUNIT_TEST_FIXTURE(SdImportTest, testStrictOOXML)
1319 createSdImpressDoc("strict_ooxml.pptx");
1321 SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
1322 CPPUNIT_ASSERT(pXImpressDocument);
1323 SdDrawDocument* pDoc = pXImpressDocument->GetDoc();
1324 CPPUNIT_ASSERT_MESSAGE("no document", pDoc != nullptr);
1325 getShapeFromPage(0, 0);
1328 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc870237)
1330 createSdImpressDoc("pptx/bnc870237.pptx");
1331 const SdrPage* pPage = GetPage(1);
1333 // Simulate a:ext inside dsp:txXfrm with changing the lower distance
1334 const SdrObjGroup* pGroupObj = dynamic_cast<SdrObjGroup*>(pPage->GetObj(0));
1335 const SdrObject* pObj = pGroupObj->GetSubList()->GetObj(1);
1336 CPPUNIT_ASSERT_MESSAGE("no object", pObj != nullptr);
1337 CPPUNIT_ASSERT_EQUAL(sal_Int32(-158), pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST).GetValue());
1338 CPPUNIT_ASSERT_EQUAL(sal_Int32(9760), pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST).GetValue());
1339 CPPUNIT_ASSERT_EQUAL(sal_Int32(-158), pObj->GetMergedItem(SDRATTR_TEXT_RIGHTDIST).GetValue());
1340 CPPUNIT_ASSERT_EQUAL(sal_Int32(-158), pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST).GetValue());
1343 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf150789)
1345 createSdImpressDoc("pptx/tdf150789.pptx");
1346 const SdrPage* pPage = GetPage(1);
1348 // Simulate a:ext inside dsp:txXfrm with changing the lower distance of prst="upArrowCallout" textbox
1349 const SdrObjGroup* pGroupObj = dynamic_cast<SdrObjGroup*>(pPage->GetObj(0));
1351 const std::array<size_t, 2> nShapes = { 4, 7 };
1352 for (auto i : nShapes)
1354 const SdrObject* pObj = pGroupObj->GetSubList()->GetObj(i);
1355 CPPUNIT_ASSERT_MESSAGE("no object", pObj != nullptr);
1357 OUString sShapeType;
1358 const SdrCustomShapeGeometryItem& rGeometryItem(
1359 pObj->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
1360 const css::uno::Any aAny = *rGeometryItem.GetPropertyValueByName("Type");
1361 if (aAny.hasValue())
1362 aAny >>= sShapeType;
1363 CPPUNIT_ASSERT_EQUAL(OUString("ooxml-upArrowCallout"), sShapeType);
1364 CPPUNIT_ASSERT_EQUAL(sal_Int32(395),
1365 pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST).GetValue());
1366 CPPUNIT_ASSERT_EQUAL(sal_Int32(1424),
1367 pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST).GetValue());
1368 CPPUNIT_ASSERT_EQUAL(sal_Int32(395),
1369 pObj->GetMergedItem(SDRATTR_TEXT_RIGHTDIST).GetValue());
1370 CPPUNIT_ASSERT_EQUAL(sal_Int32(395), pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST).GetValue());
1374 CPPUNIT_TEST_FIXTURE(SdImportTest, testCreationDate)
1376 createSdImpressDoc("fdo71434.pptx");
1377 uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(
1378 mxComponent, uno::UNO_QUERY);
1379 uno::Reference<document::XDocumentProperties> xDocumentProperties
1380 = xDocumentPropertiesSupplier->getDocumentProperties();
1381 util::DateTime aDate = xDocumentProperties->getCreationDate();
1382 OUStringBuffer aBuffer;
1383 sax::Converter::convertDateTime(aBuffer, aDate, nullptr);
1384 // Metadata wasn't imported, this was 0000-00-00.
1385 CPPUNIT_ASSERT_EQUAL(u"2013-11-09T10:37:56"_ustr, aBuffer.makeStringAndClear());
1388 CPPUNIT_TEST_FIXTURE(SdImportTest, testMultiColTexts)
1390 createSdImpressDoc("pptx/multicol.pptx");
1391 const SdrPage* pPage = GetPage(1);
1393 auto pTextObj = DynCastSdrTextObj(pPage->GetObj(0));
1394 CPPUNIT_ASSERT(pTextObj);
1396 CPPUNIT_ASSERT_EQUAL(sal_Int16(2), pTextObj->GetTextColumnsNumber());
1397 CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), pTextObj->GetTextColumnsSpacing());
1399 auto pMasterTextObj = DynCastSdrTextObj(pPage->TRG_GetMasterPage().GetObj(0));
1400 CPPUNIT_ASSERT(pMasterTextObj);
1402 CPPUNIT_ASSERT_EQUAL(sal_Int16(2), pMasterTextObj->GetTextColumnsNumber());
1403 CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), pMasterTextObj->GetTextColumnsSpacing());
1405 uno::Reference<text::XTextRange> xText(pMasterTextObj->getUnoShape(), uno::UNO_QUERY_THROW);
1406 CPPUNIT_ASSERT_EQUAL(u"mastershape1\nmastershape2"_ustr, xText->getString());
1409 CPPUNIT_TEST_FIXTURE(SdImportTest, testPredefinedTableStyle)
1411 // 073A0DAA-6AF3-43AB-8588-CEC1D06C72B9 (Medium Style 2)
1412 createSdImpressDoc("pptx/predefined-table-style.pptx");
1413 const SdrPage* pPage = GetPage(1);
1415 sdr::table::SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1416 CPPUNIT_ASSERT(pTableObj);
1418 uno::Reference<table::XCellRange> xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1419 uno::Reference<beans::XPropertySet> xCell;
1420 Color nColor;
1422 xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
1423 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1424 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nColor);
1426 xCell.set(xTable->getCellByPosition(0, 1), uno::UNO_QUERY_THROW);
1427 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1428 CPPUNIT_ASSERT_EQUAL(COL_GRAY3, nColor);
1430 xCell.set(xTable->getCellByPosition(0, 2), uno::UNO_QUERY_THROW);
1431 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1432 CPPUNIT_ASSERT_EQUAL(Color(0xe7e7e7), nColor);
1435 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc887225)
1437 createSdImpressDoc("pptx/bnc887225.pptx");
1438 // In the document, lastRow and lastCol table properties are used.
1439 // Make sure styles are set properly for individual cells.
1441 const SdrPage* pPage = GetPage(1);
1443 sdr::table::SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(2));
1444 CPPUNIT_ASSERT(pTableObj);
1445 uno::Reference<table::XCellRange> xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1446 uno::Reference<beans::XPropertySet> xCell;
1447 Color nColor;
1449 xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
1450 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1451 CPPUNIT_ASSERT_EQUAL(Color(0x5b9bd5), nColor);
1453 xCell.set(xTable->getCellByPosition(0, 1), uno::UNO_QUERY_THROW);
1454 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1455 CPPUNIT_ASSERT_EQUAL(Color(0x5b9bd5), nColor);
1457 xCell.set(xTable->getCellByPosition(1, 1), uno::UNO_QUERY_THROW);
1458 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1459 CPPUNIT_ASSERT_EQUAL(Color(0xd1deef), nColor);
1461 xCell.set(xTable->getCellByPosition(1, 2), uno::UNO_QUERY_THROW);
1462 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1463 CPPUNIT_ASSERT_EQUAL(Color(0xe9eff7), nColor);
1465 xCell.set(xTable->getCellByPosition(1, 4), uno::UNO_QUERY_THROW);
1466 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1467 CPPUNIT_ASSERT_EQUAL(Color(0x5b9bd5), nColor);
1469 xCell.set(xTable->getCellByPosition(3, 2), uno::UNO_QUERY_THROW);
1470 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1471 CPPUNIT_ASSERT_EQUAL(Color(0x5b9bd5), nColor);
1473 xCell.set(xTable->getCellByPosition(3, 4), uno::UNO_QUERY_THROW);
1474 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1475 CPPUNIT_ASSERT_EQUAL(Color(0x5b9bd5), nColor);
1478 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc584721_1)
1480 // Title text shape on the master page contained wrong text.
1482 createSdImpressDoc("pptx/bnc584721_1_2.pptx");
1484 const SdrPage* pPage = &(GetPage(1)->TRG_GetMasterPage());
1485 SdrObject* pObj = pPage->GetObj(0);
1486 SdrTextObj* pTxtObj = DynCastSdrTextObj(pObj);
1487 CPPUNIT_ASSERT_MESSAGE("no text object", pTxtObj != nullptr);
1488 const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
1489 CPPUNIT_ASSERT_EQUAL(u"Click to edit Master title style"_ustr, aEdit.GetText(0));
1492 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc584721_2)
1494 // Import created an extra/unneeded outliner shape on the master slide next to the imported title shape.
1496 createSdImpressDoc("pptx/bnc584721_1_2.pptx");
1498 const SdrPage* pPage = &(GetPage(1)->TRG_GetMasterPage());
1499 CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
1502 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc591147)
1504 createSdImpressDoc("pptx/bnc591147.pptx");
1506 // In the document, there are two slides with media files.
1507 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
1508 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xDoc->getDrawPages()->getCount());
1510 // First page has video file inserted
1511 uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0),
1512 uno::UNO_QUERY_THROW);
1513 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xPage->getCount());
1515 //uno::Reference< drawing::XShape > xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW );
1516 uno::Reference<beans::XPropertySet> xPropSet(getShape(0, xPage));
1517 OUString sVideoURL(u"emptyURL"_ustr);
1518 bool bSuccess = xPropSet->getPropertyValue(u"MediaURL"_ustr) >>= sVideoURL;
1519 CPPUNIT_ASSERT_MESSAGE("MediaURL property is not set", bSuccess);
1520 CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sVideoURL.isEmpty());
1522 // Second page has audio file inserted
1523 xPage.set(xDoc->getDrawPages()->getByIndex(1), uno::UNO_QUERY_THROW);
1524 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xPage->getCount());
1526 xPropSet.set(getShape(0, xPage));
1527 OUString sAudioURL(u"emptyURL"_ustr);
1528 bSuccess = xPropSet->getPropertyValue(u"MediaURL"_ustr) >>= sAudioURL;
1529 CPPUNIT_ASSERT_MESSAGE("MediaURL property is not set", bSuccess);
1530 CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sAudioURL.isEmpty());
1532 CPPUNIT_ASSERT_MESSAGE("sAudioURL and sVideoURL should not be equal", sAudioURL != sVideoURL);
1535 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc584721_4)
1537 // Black text was imported as white because of wrong caching mechanism
1539 createSdImpressDoc("pptx/bnc584721_4.pptx");
1540 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(1, 1));
1542 // Get first paragraph of the text
1543 uno::Reference<text::XTextRange> const xParagraph(getParagraphFromShape(0, xShape));
1545 // Get first run of the paragraph
1546 uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
1547 uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW);
1548 Color nCharColor;
1549 xPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
1551 // Color should be black
1552 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nCharColor);
1555 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc904423)
1557 // Here the problem was that different fill properties were applied in wrong order on the shape
1558 // Right order: 1) master slide fill style, 2) theme, 3) direct formatting
1560 createSdImpressDoc("pptx/bnc904423.pptx");
1562 const SdrPage* pPage = GetPage(1);
1563 // First shape's background color is defined on master slide
1565 SdrObject* const pObj = pPage->GetObj(0);
1566 CPPUNIT_ASSERT(pObj);
1568 const XFillStyleItem& rStyleItem = pObj->GetMergedItem(XATTR_FILLSTYLE);
1569 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1570 const XFillColorItem& rColorItem = pObj->GetMergedItem(XATTR_FILLCOLOR);
1571 CPPUNIT_ASSERT_EQUAL(Color(0x00CC99), rColorItem.GetColorValue());
1574 // Second shape's background color is defined by theme
1576 SdrObject* const pObj = pPage->GetObj(1);
1577 CPPUNIT_ASSERT(pObj);
1579 const XFillStyleItem& rStyleItem = pObj->GetMergedItem(XATTR_FILLSTYLE);
1580 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1581 const XFillColorItem& rColorItem = pObj->GetMergedItem(XATTR_FILLCOLOR);
1582 CPPUNIT_ASSERT_EQUAL(Color(0x3333CC), rColorItem.GetColorValue());
1585 // Third shape's background color is defined by direct formatting
1587 SdrObject* const pObj = pPage->GetObj(2);
1588 CPPUNIT_ASSERT(pObj);
1590 const XFillStyleItem& rStyleItem = pObj->GetMergedItem(XATTR_FILLSTYLE);
1591 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
1592 const XFillColorItem& rColorItem = pObj->GetMergedItem(XATTR_FILLCOLOR);
1593 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, rColorItem.GetColorValue());
1597 CPPUNIT_TEST_FIXTURE(SdImportTest, testShapeLineStyle)
1599 // Here the problem was that different line properties were applied in wrong order on the shape
1600 // Right order: 1) master slide line style, 2) theme, 3) direct formatting
1601 createSdImpressDoc("pptx/ShapeLineProperties.pptx");
1603 const SdrPage* pPage = GetPage(1);
1604 // First shape's line style is defined on master slide
1606 SdrObject* const pObj = pPage->GetObj(0);
1607 CPPUNIT_ASSERT(pObj);
1609 const XLineStyleItem& rStyleItem = pObj->GetMergedItem(XATTR_LINESTYLE);
1610 CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_DASH, rStyleItem.GetValue());
1612 const XLineColorItem& rColorItem = pObj->GetMergedItem(XATTR_LINECOLOR);
1613 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, rColorItem.GetColorValue());
1615 const XLineWidthItem& rWidthItem = pObj->GetMergedItem(XATTR_LINEWIDTH);
1616 CPPUNIT_ASSERT_EQUAL(sal_Int32(132), rWidthItem.GetValue());
1619 // Second shape's line style is defined by theme
1621 SdrObject* const pObj = pPage->GetObj(1);
1622 CPPUNIT_ASSERT(pObj);
1624 const XLineStyleItem& rStyleItem = pObj->GetMergedItem(XATTR_LINESTYLE);
1625 CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
1627 const XLineColorItem& rColorItem = pObj->GetMergedItem(XATTR_LINECOLOR);
1628 CPPUNIT_ASSERT_EQUAL(Color(0x3333CC), rColorItem.GetColorValue());
1630 const XLineWidthItem& rWidthItem = pObj->GetMergedItem(XATTR_LINEWIDTH);
1631 CPPUNIT_ASSERT_EQUAL(sal_Int32(35), rWidthItem.GetValue());
1634 // Third shape's line style is defined by direct formatting
1636 SdrObject* const pObj = pPage->GetObj(2);
1637 CPPUNIT_ASSERT(pObj);
1639 const XLineStyleItem& rStyleItem = pObj->GetMergedItem(XATTR_LINESTYLE);
1640 CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
1642 const XLineColorItem& rColorItem = pObj->GetMergedItem(XATTR_LINECOLOR);
1643 CPPUNIT_ASSERT_EQUAL(Color(0x7030A0), rColorItem.GetColorValue());
1645 const XLineWidthItem& rWidthItem = pObj->GetMergedItem(XATTR_LINEWIDTH);
1646 CPPUNIT_ASSERT_EQUAL(sal_Int32(176), rWidthItem.GetValue());
1650 CPPUNIT_TEST_FIXTURE(SdImportTest, testTableBorderLineStyle)
1652 createSdImpressDoc("pptx/tableBorderLineStyle.pptx");
1654 // TODO: If you are working on improvement of table border line style
1655 // support, then expect this unit test to fail.
1657 const sal_Int16 nObjBorderLineStyles[]
1658 = { ::table::BorderLineStyle::DASHED, ::table::BorderLineStyle::DASH_DOT_DOT,
1659 ::table::BorderLineStyle::DASH_DOT, ::table::BorderLineStyle::DOTTED,
1660 ::table::BorderLineStyle::DASHED, ::table::BorderLineStyle::DOTTED,
1661 ::table::BorderLineStyle::DASHED, ::table::BorderLineStyle::DASH_DOT,
1662 ::table::BorderLineStyle::DASH_DOT, ::table::BorderLineStyle::SOLID,
1663 ::table::BorderLineStyle::NONE };
1665 const SdrPage* pPage = GetPage(1);
1666 CPPUNIT_ASSERT_EQUAL(SAL_N_ELEMENTS(nObjBorderLineStyles), pPage->GetObjCount());
1668 sdr::table::SdrTableObj* pTableObj;
1669 uno::Reference<table::XCellRange> xTable;
1670 uno::Reference<beans::XPropertySet> xCell;
1671 table::BorderLine2 aBorderLine;
1673 for (size_t i = 0; i < SAL_N_ELEMENTS(nObjBorderLineStyles); i++)
1675 pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(i));
1676 CPPUNIT_ASSERT(pTableObj);
1677 xTable.set(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1678 xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
1679 xCell->getPropertyValue(u"TopBorder"_ustr) >>= aBorderLine;
1680 if (aBorderLine.LineWidth > 0)
1682 CPPUNIT_ASSERT_EQUAL(nObjBorderLineStyles[i], aBorderLine.LineStyle);
1687 CPPUNIT_TEST_FIXTURE(SdImportTest, testTableMergedCellsBorderLineStyle)
1689 createSdImpressDoc("pptx/tdf149865.pptx");
1691 const SdrPage* pPage = GetPage(1);
1693 sdr::table::SdrTableObj* pTableObj;
1694 uno::Reference<table::XCellRange> xTable;
1695 uno::Reference<beans::XPropertySet> xCell;
1696 table::BorderLine2 aBorderLine;
1698 pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1699 CPPUNIT_ASSERT(pTableObj);
1700 xTable.set(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1701 xCell.set(xTable->getCellByPosition(4, 1), uno::UNO_QUERY_THROW);
1702 xCell->getPropertyValue(u"RightBorder"_ustr) >>= aBorderLine;
1703 table::BorderLine2 expectedRight(0x30ba78, 0, 17, 0, 0, 17);
1704 CPPUNIT_ASSERT_EQUAL(expectedRight.LineStyle, aBorderLine.LineStyle);
1705 CPPUNIT_ASSERT_EQUAL(expectedRight.Color, aBorderLine.Color);
1706 CPPUNIT_ASSERT_EQUAL(expectedRight.LineWidth, aBorderLine.LineWidth);
1709 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc862510_6)
1711 // Black text was imported instead of gray
1713 createSdImpressDoc("pptx/bnc862510_6.pptx");
1714 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
1716 // Get first paragraph of the text
1717 uno::Reference<text::XTextRange> const xParagraph(getParagraphFromShape(0, xShape));
1719 // Get first run of the paragraph
1720 uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
1721 uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW);
1722 Color nCharColor;
1723 xPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
1725 // Color should be gray
1726 CPPUNIT_ASSERT_EQUAL(Color(0x8B8B8B), nCharColor);
1729 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc862510_7)
1731 // Title shape's text was aligned to left instead of center.
1733 createSdImpressDoc("pptx/bnc862510_7.pptx");
1734 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
1736 // Get first paragraph
1737 uno::Reference<text::XTextRange> const xParagraph(getParagraphFromShape(0, xShape));
1738 uno::Reference<beans::XPropertySet> xPropSet(xParagraph, uno::UNO_QUERY_THROW);
1740 sal_Int16 nParaAdjust = 0;
1741 xPropSet->getPropertyValue(u"ParaAdjust"_ustr) >>= nParaAdjust;
1742 CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER,
1743 static_cast<style::ParagraphAdjust>(nParaAdjust));
1746 #if ENABLE_PDFIMPORT
1747 // These tests use the old PDF-importing logic, which imports PDF elements as
1748 // SD elements. This suffered many issues, and therefore wasn't ideal.
1749 // The old PDF importer relied on an open-source project (xpdf) with an
1750 // incompatible license (gpl), which has to be interfaced via an out-of-process
1751 // library wrapper process. The resulting imported document was inaccurate
1752 // and often very slow and with large memory footprint.
1753 // Instead, PDFium offers state-of-the-art PDF importing logic,
1754 // which is well-maintained and renders PDFs into images with high accuracy.
1755 // So, the idea is to import PDFs as images using PDFium, which has a very
1756 // high quality (and is much faster) than importing individual editable elements.
1757 // So that's the "new" way of importing.
1758 // The user then breaks the image to editable elements (which is not perfect,
1759 // but very close to the old way), only if they need editing ability.
1760 // PDFium should overall be better, and where it isn't, we just need to improve it.
1761 // So these tests aren't really useful anymore. They should be modified to do
1762 // import+break and then check the results. But that isn't straight-forward and
1763 // currently await volunteering time to implement.
1765 CPPUNIT_TEST_FIXTURE(SdImportTest, testPDFImportShared)
1767 auto pPdfium = vcl::pdf::PDFiumLibrary::get();
1768 if (!pPdfium)
1770 return;
1773 comphelper::LibreOfficeKit::setActive();
1775 createSdDrawDoc("pdf/multipage.pdf");
1776 SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
1777 CPPUNIT_ASSERT(pXImpressDocument);
1778 SdDrawDocument* pDoc = pXImpressDocument->GetDoc();
1780 // This test is to verify that we share the PDF stream linked to each
1781 // Graphic instance in the imported document.
1782 // Since we import PDFs as images, we support attaching the original
1783 // PDF with each image to allow for advanced editing.
1784 // Here we iterate over all Graphic instances embedded in the pages
1785 // and verify that they all point to the same object in memory.
1786 std::vector<Graphic> aGraphics;
1788 for (int nPageIndex = 0; nPageIndex < pDoc->GetPageCount(); ++nPageIndex)
1790 const SdrPage* pPage = GetPage(nPageIndex);
1791 if (pPage == nullptr)
1792 break;
1794 for (size_t nObjIndex = 0; nObjIndex < pPage->GetObjCount(); ++nObjIndex)
1796 SdrObject* pObject = pPage->GetObj(nObjIndex);
1797 if (pObject == nullptr)
1798 continue;
1800 SdrGrafObj* pSdrGrafObj = dynamic_cast<SdrGrafObj*>(pObject);
1801 if (pSdrGrafObj == nullptr)
1802 continue;
1804 const GraphicObject aGraphicObject = pSdrGrafObj->GetGraphicObject().GetGraphic();
1805 const Graphic& rGraphic = aGraphicObject.GetGraphic();
1806 CPPUNIT_ASSERT_MESSAGE(
1807 "After loading, the PDF shouldn't have the primitive sequence created yet",
1808 !rGraphic.getVectorGraphicData()->isPrimitiveSequenceCreated());
1809 aGraphics.push_back(rGraphic);
1813 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected more than one page.", size_t(9), aGraphics.size());
1815 Graphic const& rFirstGraphic = aGraphics[0];
1817 for (size_t i = 0; i < aGraphics.size(); ++i)
1819 Graphic const& rGraphic = aGraphics[i];
1820 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1821 "Expected all PDF streams to be identical.",
1822 rFirstGraphic.getVectorGraphicData()->getBinaryDataContainer().getData(),
1823 rGraphic.getVectorGraphicData()->getBinaryDataContainer().getData());
1825 CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all GfxLinks to be identical.",
1826 rFirstGraphic.GetSharedGfxLink().get(),
1827 rGraphic.GetSharedGfxLink().get());
1829 CPPUNIT_ASSERT_EQUAL_MESSAGE("Page number doesn't match expected", sal_Int32(i),
1830 rGraphic.getPageNumber());
1833 mxComponent->dispose();
1834 mxComponent.clear();
1836 comphelper::LibreOfficeKit::setActive(false);
1839 #if defined(IMPORT_PDF_ELEMENTS)
1841 CPPUNIT_TEST_FIXTURE(SdImportTest, testPDFImport)
1843 createSdDrawDoc("pdf/txtpic.pdf");
1844 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
1845 uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0),
1846 uno::UNO_QUERY_THROW);
1847 CPPUNIT_ASSERT_EQUAL_MESSAGE("no exactly two shapes", static_cast<sal_Int32>(2),
1848 xPage->getCount());
1850 uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
1851 uno::Reference<text::XText> xText
1852 = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
1853 CPPUNIT_ASSERT_MESSAGE("not a text shape", xText.is());
1856 CPPUNIT_TEST_FIXTURE(SdImportTest, testPDFImportSkipImages)
1858 auto pParams = std::make_shared<SfxAllItemSet>(SfxGetpApp()->GetPool());
1859 pParams->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, "SkipImages"));
1861 createSdDrawDoc("pdf/txtpic.pdf"), PDF, pParams);
1862 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
1863 uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0),
1864 uno::UNO_QUERY_THROW);
1865 CPPUNIT_ASSERT_EQUAL_MESSAGE("no exactly one shape", static_cast<sal_Int32>(1),
1866 xPage->getCount());
1868 uno::Reference<drawing::XShape> xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW);
1869 uno::Reference<text::XText> xText
1870 = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
1871 CPPUNIT_ASSERT_MESSAGE("not a text shape", xText.is());
1874 #endif
1875 #endif
1877 CPPUNIT_TEST_FIXTURE(SdImportTest, testBulletSuffix)
1879 createSdImpressDoc("pptx/n83889.pptx");
1881 // check suffix of the char bullet
1882 const SdrPage* pPage = GetPage(1);
1883 SdrTextObj* pTxtObj = DynCastSdrTextObj(pPage->GetObj(0));
1884 CPPUNIT_ASSERT_MESSAGE("no text object", pTxtObj != nullptr);
1885 const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
1886 const SvxNumBulletItem* pNumFmt = aEdit.GetParaAttribs(1).GetItem(EE_PARA_NUMBULLET);
1887 CPPUNIT_ASSERT(pNumFmt);
1888 CPPUNIT_ASSERT_EQUAL_MESSAGE("Bullet's suffix is wrong!",
1889 pNumFmt->GetNumRule().GetLevel(0).GetSuffix(), OUString());
1892 CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc910045)
1894 // Problem with table style which defines cell color with fill style
1896 createSdImpressDoc("pptx/bnc910045.pptx");
1897 const SdrPage* pPage = GetPage(1);
1899 sdr::table::SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1900 CPPUNIT_ASSERT(pTableObj);
1901 uno::Reference<table::XCellRange> xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
1902 uno::Reference<beans::XPropertySet> xCell;
1903 Color nColor;
1905 xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
1906 xCell->getPropertyValue(u"FillColor"_ustr) >>= nColor;
1907 CPPUNIT_ASSERT_EQUAL(Color(0x4f81bd), nColor);
1910 CPPUNIT_TEST_FIXTURE(SdImportTest, testRowHeight)
1912 createSdImpressDoc("pptx/n80340.pptx");
1913 const SdrPage* pPage = GetPage(1);
1915 sdr::table::SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1916 CPPUNIT_ASSERT(pTableObj);
1918 sal_Int32 nHeight;
1919 uno::Reference<css::table::XTable> xTable(pTableObj->getTable(), uno::UNO_SET_THROW);
1920 uno::Reference<css::table::XTableRows> xRows(xTable->getRows(), uno::UNO_SET_THROW);
1921 uno::Reference<beans::XPropertySet> xRefRow(xRows->getByIndex(0), uno::UNO_QUERY_THROW);
1922 xRefRow->getPropertyValue(u"Height"_ustr) >>= nHeight;
1923 CPPUNIT_ASSERT_EQUAL(sal_Int32(508), nHeight);
1925 createSdImpressDoc("pptx/tablescale.pptx");
1926 const SdrPage* pPage2 = GetPage(1);
1928 sdr::table::SdrTableObj* pTableObj2 = dynamic_cast<sdr::table::SdrTableObj*>(pPage2->GetObj(0));
1929 CPPUNIT_ASSERT(pTableObj2);
1931 uno::Reference<css::table::XTable> xTable2(pTableObj2->getTable(), uno::UNO_SET_THROW);
1932 uno::Reference<css::table::XTableRows> xRows2(xTable2->getRows(), uno::UNO_SET_THROW);
1934 for (sal_Int32 nRow = 0; nRow < 7; ++nRow)
1936 uno::Reference<beans::XPropertySet> xRefRow2(xRows2->getByIndex(nRow),
1937 uno::UNO_QUERY_THROW);
1938 xRefRow2->getPropertyValue(u"Height"_ustr) >>= nHeight;
1939 CPPUNIT_ASSERT_EQUAL(sal_Int32(800), nHeight);
1943 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf93830)
1945 // Text shape offset was ignored
1947 createSdImpressDoc("pptx/tdf93830.pptx");
1948 uno::Reference<drawing::XDrawPage> xPage(getPage(0));
1950 // Get the first text box from group shape
1951 uno::Reference<container::XIndexAccess> xShape(xPage->getByIndex(0), uno::UNO_QUERY);
1952 uno::Reference<beans::XPropertySet> xPropSet(xShape->getByIndex(3), uno::UNO_QUERY);
1953 CPPUNIT_ASSERT_MESSAGE("no textbox shape", xPropSet.is());
1955 sal_Int32 nTextLeftDistance = 0;
1956 xPropSet->getPropertyValue(u"TextLeftDistance"_ustr) >>= nTextLeftDistance;
1957 CPPUNIT_ASSERT_EQUAL(sal_Int32(4024), nTextLeftDistance);
1960 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf127129)
1962 createSdImpressDoc("pptx/tdf127129.pptx");
1963 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
1964 uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xShape));
1965 uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
1966 uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW);
1968 Color nCharColor;
1969 xPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
1970 CPPUNIT_ASSERT_EQUAL(COL_BLACK, nCharColor);
1972 // Without the accompanying fix in place, the highlight would be -1
1973 Color nCharBackColor;
1974 xPropSet->getPropertyValue(u"CharBackColor"_ustr) >>= nCharBackColor;
1975 CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, nCharBackColor);
1977 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf93097)
1979 // Throwing metadata import aborted the filter, check that metadata is now imported.
1981 createSdImpressDoc("pptx/tdf93097.pptx");
1982 uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(
1983 mxComponent, uno::UNO_QUERY);
1984 uno::Reference<document::XDocumentProperties> xDocumentProperties
1985 = xDocumentPropertiesSupplier->getDocumentProperties();
1986 CPPUNIT_ASSERT_EQUAL(u"ss"_ustr, xDocumentProperties->getTitle());
1989 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf62255)
1991 createSdImpressDoc("pptx/tdf62255.pptx");
1992 const SdrPage* pPage = GetPage(1);
1994 sdr::table::SdrTableObj* pTableObj;
1995 pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
1996 CPPUNIT_ASSERT(pTableObj);
1998 css::uno::Any aAny;
1999 uno::Reference<table::XCellRange> xTable;
2000 uno::Reference<beans::XPropertySet> xCell;
2001 xTable.set(pTableObj->getTable(), uno::UNO_QUERY_THROW);
2002 xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
2003 aAny = xCell->getPropertyValue(u"FillStyle"_ustr);
2005 if (aAny.hasValue())
2007 drawing::FillStyle aFillStyle;
2008 aAny >>= aFillStyle;
2009 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, aFillStyle);
2013 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf89927)
2015 createSdImpressDoc("pptx/tdf89927.pptx");
2016 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
2017 uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xShape));
2018 uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
2019 uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW);
2021 Color nCharColor;
2022 xPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
2023 CPPUNIT_ASSERT_EQUAL(COL_WHITE, nCharColor);
2026 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf103800)
2028 createSdImpressDoc("pptx/tdf103800.pptx");
2029 uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0));
2030 uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xShape));
2031 uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
2032 uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW);
2034 Color nCharColor;
2035 xPropSet->getPropertyValue(u"CharColor"_ustr) >>= nCharColor;
2036 CPPUNIT_ASSERT_EQUAL(Color(0xC00000), nCharColor);
2039 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf151767)
2041 createSdImpressDoc("pptx/tdf151767.pptx");
2043 const SdrPage* pPage = GetPage(1);
2044 sdr::table::SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
2045 uno::Reference<table::XCellRange> xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
2046 uno::Reference<beans::XPropertySet> xCell(xTable->getCellByPosition(0, 0),
2047 uno::UNO_QUERY_THROW);
2049 table::BorderLine2 aLeft;
2050 xCell->getPropertyValue(u"LeftBorder"_ustr) >>= aLeft;
2051 CPPUNIT_ASSERT_EQUAL_MESSAGE("The left border is missing!", true, aLeft.LineWidth > 0);
2053 table::BorderLine2 aRight;
2054 xCell->getPropertyValue(u"RightBorder"_ustr) >>= aRight;
2055 CPPUNIT_ASSERT_EQUAL_MESSAGE("The right border is missing!", true, aRight.LineWidth > 0);
2057 table::BorderLine2 aTop;
2058 xCell->getPropertyValue(u"TopBorder"_ustr) >>= aTop;
2059 CPPUNIT_ASSERT_EQUAL_MESSAGE("The top border is missing!", true, aTop.LineWidth > 0);
2061 table::BorderLine2 aBottom;
2062 xCell->getPropertyValue(u"BottomBorder"_ustr) >>= aBottom;
2063 CPPUNIT_ASSERT_EQUAL_MESSAGE("The bottom border is missing!", true, aBottom.LineWidth > 0);
2066 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf152070)
2068 createSdImpressDoc("pptx/tdf152070.pptx");
2070 uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW);
2071 uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
2072 uno::Reference<beans::XPropertySet> xPropSet(xPage, uno::UNO_QUERY_THROW);
2073 uno::Reference<beans::XPropertySet> xBackgroundProps(
2074 xPropSet->getPropertyValue(u"Background"_ustr).get<uno::Reference<beans::XPropertySet>>());
2076 CPPUNIT_ASSERT_EQUAL(
2077 sal_Int32(50), // 50%
2078 xBackgroundProps->getPropertyValue(u"FillBitmapPositionOffsetX"_ustr).get<sal_Int32>());
2079 CPPUNIT_ASSERT_EQUAL(
2080 sal_Int32(83), // 83%
2081 xBackgroundProps->getPropertyValue(u"FillBitmapPositionOffsetY"_ustr).get<sal_Int32>());
2084 CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf143603)
2086 createSdImpressDoc("odp/tdf143603.fodp");
2087 SdXImpressDocument* pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
2088 CPPUNIT_ASSERT(pXImpressDocument);
2089 SdDrawDocument* pDoc = pXImpressDocument->GetDoc();
2090 CPPUNIT_ASSERT(pDoc);
2091 // Loading FODP used to record UNDO entries - this was 2
2092 CPPUNIT_ASSERT_EQUAL(size_t(0), pDoc->GetUndoManager()->GetUndoActionCount());
2095 CPPUNIT_PLUGIN_IMPLEMENT();
2097 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */