Line data Source code
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 "charttest.hxx"
11 :
12 : #include <test/xmltesttools.hxx>
13 :
14 : #include <com/sun/star/chart/ErrorBarStyle.hpp>
15 : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
16 : #include <com/sun/star/lang/XServiceName.hpp>
17 : #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
18 : #include <com/sun/star/text/XTextDocument.hpp>
19 : #include <com/sun/star/text/XTextFramesSupplier.hpp>
20 : #include <com/sun/star/drawing/LineStyle.hpp>
21 :
22 : #include <unotools/ucbstreamhelper.hxx>
23 : #include <rtl/strbuf.hxx>
24 :
25 : #include <libxml/xpathInternals.h>
26 : #include <libxml/parserInternals.h>
27 :
28 : #include <algorithm>
29 :
30 : using uno::Reference;
31 : using beans::XPropertySet;
32 :
33 164 : class Chart2ExportTest : public ChartTest, public XmlTestTools
34 : {
35 : protected:
36 :
37 : virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) SAL_OVERRIDE;
38 : public:
39 82 : Chart2ExportTest() : ChartTest() {}
40 : void test();
41 : void testErrorBarXLSX();
42 : void testTrendline();
43 : void testTrendlineOOXML();
44 : void testTrendlineXLS();
45 : void testStockChart();
46 : void testBarChart();
47 : void testCrosses();
48 : void testScatterChartTextXValues();
49 : void testChartDataTable();
50 : void testChartExternalData();
51 : void testEmbeddingsGrabBag();
52 : void testAreaChartLoad();
53 : void testUpDownBars();
54 : void testDoughnutChart();
55 : void testDisplayUnits();
56 : // void testFdo74115WallGradientFill();
57 : void testFdo74115WallBitmapFill();
58 : void testBarChartRotation();
59 : void testShapeFollowedByChart();
60 : void testPieChartDataLabels();
61 : void testSeriesIdxOrder();
62 : void testScatterPlotLabels();
63 : void testErrorBarDataRangeODS();
64 : void testChartCrash();
65 : void testPieChartRotation();
66 : void testEmbeddingsOleObjectGrabBag();
67 : void testGapWidthXLSX();
68 : void testSmoothedLines();
69 : void testLabelStringODS();
70 : void testFdo78290LineChartMarkerX();
71 : void testFdo78290ScatterChartMarkerX();
72 : void testFdo78290CombinationChartMarkerX();
73 : void testAxisNumberFormatODS();
74 : void testDataLabelBordersDOCX();
75 : void testDataLabel3DChartDOCX();
76 : void testDataLabelBarChartDOCX();
77 : void testDataLabelClusteredBarChartDOCX();
78 : void testDataLabelRadarChartDOCX();
79 : void testDataLabelDoughnutChartDOCX();
80 : void testDataLabelAreaChartDOCX();
81 : void testDataLabelDefaultLineChartDOCX();
82 :
83 4 : CPPUNIT_TEST_SUITE(Chart2ExportTest);
84 2 : CPPUNIT_TEST(test);
85 2 : CPPUNIT_TEST(testErrorBarXLSX);
86 2 : CPPUNIT_TEST(testTrendline);
87 2 : CPPUNIT_TEST(testTrendlineOOXML);
88 2 : CPPUNIT_TEST(testTrendlineXLS);
89 2 : CPPUNIT_TEST(testStockChart);
90 2 : CPPUNIT_TEST(testBarChart);
91 2 : CPPUNIT_TEST(testCrosses);
92 2 : CPPUNIT_TEST(testScatterChartTextXValues);
93 2 : CPPUNIT_TEST(testChartDataTable);
94 2 : CPPUNIT_TEST(testChartExternalData);
95 2 : CPPUNIT_TEST(testEmbeddingsGrabBag);
96 2 : CPPUNIT_TEST(testAreaChartLoad);
97 2 : CPPUNIT_TEST(testUpDownBars);
98 2 : CPPUNIT_TEST(testDoughnutChart);
99 2 : CPPUNIT_TEST(testDisplayUnits);
100 : // CPPUNIT_TEST(testFdo74115WallGradientFill);
101 2 : CPPUNIT_TEST(testFdo74115WallBitmapFill);
102 2 : CPPUNIT_TEST(testBarChartRotation);
103 2 : CPPUNIT_TEST(testShapeFollowedByChart);
104 2 : CPPUNIT_TEST(testPieChartDataLabels);
105 2 : CPPUNIT_TEST(testSeriesIdxOrder);
106 2 : CPPUNIT_TEST(testScatterPlotLabels);
107 2 : CPPUNIT_TEST(testErrorBarDataRangeODS);
108 2 : CPPUNIT_TEST(testChartCrash);
109 2 : CPPUNIT_TEST(testPieChartRotation);
110 2 : CPPUNIT_TEST(testEmbeddingsOleObjectGrabBag);
111 2 : CPPUNIT_TEST(testGapWidthXLSX);
112 2 : CPPUNIT_TEST(testSmoothedLines);
113 2 : CPPUNIT_TEST(testLabelStringODS);
114 2 : CPPUNIT_TEST(testFdo78290LineChartMarkerX);
115 2 : CPPUNIT_TEST(testFdo78290ScatterChartMarkerX);
116 2 : CPPUNIT_TEST(testFdo78290CombinationChartMarkerX);
117 2 : CPPUNIT_TEST(testAxisNumberFormatODS);
118 2 : CPPUNIT_TEST(testDataLabelBordersDOCX);
119 2 : CPPUNIT_TEST(testDataLabel3DChartDOCX);
120 2 : CPPUNIT_TEST(testDataLabelBarChartDOCX);
121 2 : CPPUNIT_TEST(testDataLabelClusteredBarChartDOCX);
122 2 : CPPUNIT_TEST(testDataLabelRadarChartDOCX);
123 2 : CPPUNIT_TEST(testDataLabelDoughnutChartDOCX);
124 2 : CPPUNIT_TEST(testDataLabelAreaChartDOCX);
125 2 : CPPUNIT_TEST(testDataLabelDefaultLineChartDOCX);
126 4 : CPPUNIT_TEST_SUITE_END();
127 :
128 : protected:
129 : /**
130 : * Given that some problem doesn't affect the result in the importer, we
131 : * test the resulting file directly, by opening the zip file, parsing an
132 : * xml stream, and asserting an XPath expression. This method returns the
133 : * xml stream, so that you can do the asserting.
134 : */
135 : xmlDocPtr parseExport(const OUString& rDir, const OUString& rFilterFormat);
136 :
137 : };
138 :
139 2 : void Chart2ExportTest::test()
140 : {
141 2 : load("/chart2/qa/extras/data/ods/", "simple_export_chart.ods");
142 2 : reload("Calc Office Open XML");
143 2 : }
144 :
145 486 : struct CheckForChartName
146 : {
147 : private:
148 : OUString aDir;
149 :
150 : public:
151 54 : CheckForChartName( const OUString& rDir ):
152 54 : aDir(rDir) {}
153 :
154 420 : bool operator()(const OUString& rName)
155 : {
156 420 : if(!rName.startsWith(aDir))
157 366 : return false;
158 :
159 54 : if(!rName.endsWith(".xml"))
160 0 : return false;
161 :
162 54 : return true;
163 : }
164 : };
165 :
166 54 : OUString findChartFile(const OUString& rDir, uno::Reference< container::XNameAccess > xNames )
167 : {
168 54 : uno::Sequence<OUString> rNames = xNames->getElementNames();
169 54 : OUString* pElement = std::find_if(rNames.begin(), rNames.end(), CheckForChartName(rDir));
170 :
171 54 : CPPUNIT_ASSERT(pElement);
172 54 : CPPUNIT_ASSERT(pElement != rNames.end());
173 54 : return *pElement;
174 : }
175 :
176 54 : xmlDocPtr Chart2ExportTest::parseExport(const OUString& rDir, const OUString& rFilterFormat)
177 : {
178 54 : boost::shared_ptr<utl::TempFile> pTempFile = reload(rFilterFormat);
179 :
180 : // Read the XML stream we're interested in.
181 108 : uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), pTempFile->GetURL());
182 108 : uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName(findChartFile(rDir, xNameAccess)), uno::UNO_QUERY);
183 54 : CPPUNIT_ASSERT(xInputStream.is());
184 108 : boost::shared_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
185 :
186 108 : return parseXmlStream(pStream.get());
187 : }
188 :
189 88 : void Chart2ExportTest::registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx)
190 : {
191 : struct { xmlChar* pPrefix; xmlChar* pURI; } aNamespaces[] =
192 : {
193 : { BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main") },
194 : { BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml") },
195 : { BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart") },
196 : { BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main") },
197 : { BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006") },
198 : { BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape") },
199 : { BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup") },
200 : { BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing") },
201 : { BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0") },
202 : { BAD_CAST("table"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0") },
203 : { BAD_CAST("text"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0") },
204 : { BAD_CAST("xlink"), BAD_CAST("http://www.w3c.org/1999/xlink") }
205 88 : };
206 1144 : for(size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i)
207 : {
208 1056 : xmlXPathRegisterNs(pXmlXPathCtx, aNamespaces[i].pPrefix, aNamespaces[i].pURI );
209 : }
210 88 : }
211 :
212 : namespace {
213 :
214 4 : void testErrorBar( Reference< XPropertySet > xErrorBar )
215 : {
216 : sal_Int32 nErrorBarStyle;
217 8 : CPPUNIT_ASSERT(
218 4 : xErrorBar->getPropertyValue("ErrorBarStyle") >>= nErrorBarStyle);
219 4 : CPPUNIT_ASSERT_EQUAL(nErrorBarStyle, chart::ErrorBarStyle::RELATIVE);
220 4 : bool bShowPositive = bool(), bShowNegative = bool();
221 8 : CPPUNIT_ASSERT(
222 4 : xErrorBar->getPropertyValue("ShowPositiveError") >>= bShowPositive);
223 4 : CPPUNIT_ASSERT(bShowPositive);
224 8 : CPPUNIT_ASSERT(
225 4 : xErrorBar->getPropertyValue("ShowNegativeError") >>= bShowNegative);
226 4 : CPPUNIT_ASSERT(bShowNegative);
227 4 : double nVal = 0.0;
228 4 : CPPUNIT_ASSERT(xErrorBar->getPropertyValue("PositiveError") >>= nVal);
229 4 : CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 10.0, 1e-10);
230 4 : }
231 :
232 24 : void checkCommonTrendline(
233 : Reference<chart2::XRegressionCurve> xCurve,
234 : double aExpectedExtrapolateForward, double aExpectedExtrapolateBackward,
235 : bool aExpectedForceIntercept, double aExpectedInterceptValue,
236 : bool aExpectedShowEquation, bool aExpectedR2)
237 : {
238 24 : Reference<XPropertySet> xProperties( xCurve , uno::UNO_QUERY );
239 24 : CPPUNIT_ASSERT(xProperties.is());
240 :
241 24 : double aExtrapolateForward = 0.0;
242 24 : CPPUNIT_ASSERT(xProperties->getPropertyValue("ExtrapolateForward") >>= aExtrapolateForward);
243 24 : CPPUNIT_ASSERT_EQUAL(aExpectedExtrapolateForward, aExtrapolateForward);
244 :
245 24 : double aExtrapolateBackward = 0.0;
246 24 : CPPUNIT_ASSERT(xProperties->getPropertyValue("ExtrapolateBackward") >>= aExtrapolateBackward);
247 24 : CPPUNIT_ASSERT_EQUAL(aExpectedExtrapolateBackward, aExtrapolateBackward);
248 :
249 24 : bool aForceIntercept = false;
250 24 : CPPUNIT_ASSERT(xProperties->getPropertyValue("ForceIntercept") >>= aForceIntercept);
251 24 : CPPUNIT_ASSERT_EQUAL(aExpectedForceIntercept, aForceIntercept);
252 :
253 24 : if (aForceIntercept)
254 : {
255 12 : double aInterceptValue = 0.0;
256 12 : CPPUNIT_ASSERT(xProperties->getPropertyValue("InterceptValue") >>= aInterceptValue);
257 12 : CPPUNIT_ASSERT_EQUAL(aExpectedInterceptValue, aInterceptValue);
258 : }
259 :
260 48 : Reference< XPropertySet > xEquationProperties( xCurve->getEquationProperties() );
261 24 : CPPUNIT_ASSERT(xEquationProperties.is());
262 :
263 24 : bool aShowEquation = false;
264 24 : CPPUNIT_ASSERT(xEquationProperties->getPropertyValue("ShowEquation") >>= aShowEquation);
265 24 : CPPUNIT_ASSERT_EQUAL(aExpectedShowEquation, aShowEquation);
266 :
267 24 : bool aShowCorrelationCoefficient = false;
268 24 : CPPUNIT_ASSERT(xEquationProperties->getPropertyValue("ShowCorrelationCoefficient") >>= aShowCorrelationCoefficient);
269 48 : CPPUNIT_ASSERT_EQUAL(aExpectedR2, aShowCorrelationCoefficient);
270 24 : }
271 :
272 36 : void checkNameAndType(Reference<XPropertySet> xProperties, const OUString& aExpectedName, const OUString& aExpectedServiceName)
273 : {
274 36 : Reference< lang::XServiceName > xServiceName( xProperties, UNO_QUERY );
275 36 : CPPUNIT_ASSERT(xServiceName.is());
276 :
277 72 : OUString aServiceName = xServiceName->getServiceName();
278 36 : CPPUNIT_ASSERT_EQUAL(aExpectedServiceName, aServiceName);
279 :
280 72 : OUString aCurveName;
281 36 : CPPUNIT_ASSERT(xProperties->getPropertyValue("CurveName") >>= aCurveName);
282 72 : CPPUNIT_ASSERT_EQUAL(aExpectedName, aCurveName);
283 36 : }
284 :
285 12 : void checkLinearTrendline(
286 : Reference<chart2::XRegressionCurve> xCurve, const OUString& aExpectedName,
287 : double aExpectedExtrapolateForward, double aExpectedExtrapolateBackward,
288 : bool aExpectedForceIntercept, double aExpectedInterceptValue,
289 : bool aExpectedShowEquation, bool aExpectedR2)
290 : {
291 12 : Reference<XPropertySet> xProperties( xCurve , uno::UNO_QUERY );
292 12 : CPPUNIT_ASSERT(xProperties.is());
293 :
294 12 : checkNameAndType(xProperties, aExpectedName, "com.sun.star.chart2.LinearRegressionCurve");
295 :
296 : checkCommonTrendline(
297 : xCurve,
298 : aExpectedExtrapolateForward, aExpectedExtrapolateBackward,
299 : aExpectedForceIntercept, aExpectedInterceptValue,
300 12 : aExpectedShowEquation, aExpectedR2);
301 12 : }
302 :
303 12 : void checkPolynomialTrendline(
304 : Reference<chart2::XRegressionCurve> xCurve, const OUString& aExpectedName,
305 : sal_Int32 aExpectedDegree,
306 : double aExpectedExtrapolateForward, double aExpectedExtrapolateBackward,
307 : bool aExpectedForceIntercept, double aExpectedInterceptValue,
308 : bool aExpectedShowEquation, bool aExpectedR2)
309 : {
310 12 : Reference<XPropertySet> xProperties( xCurve , uno::UNO_QUERY );
311 12 : CPPUNIT_ASSERT(xProperties.is());
312 :
313 12 : checkNameAndType(xProperties, aExpectedName, "com.sun.star.chart2.PolynomialRegressionCurve");
314 :
315 12 : sal_Int32 aDegree = 2;
316 12 : CPPUNIT_ASSERT(xProperties->getPropertyValue("PolynomialDegree") >>= aDegree);
317 12 : CPPUNIT_ASSERT_EQUAL(aExpectedDegree, aDegree);
318 :
319 : checkCommonTrendline(
320 : xCurve,
321 : aExpectedExtrapolateForward, aExpectedExtrapolateBackward,
322 : aExpectedForceIntercept, aExpectedInterceptValue,
323 12 : aExpectedShowEquation, aExpectedR2);
324 12 : }
325 :
326 12 : void checkMovingAverageTrendline(
327 : Reference<chart2::XRegressionCurve> xCurve, const OUString& aExpectedName, sal_Int32 aExpectedPeriod)
328 : {
329 12 : Reference<XPropertySet> xProperties( xCurve , uno::UNO_QUERY );
330 12 : CPPUNIT_ASSERT(xProperties.is());
331 :
332 12 : checkNameAndType(xProperties, aExpectedName, "com.sun.star.chart2.MovingAverageRegressionCurve");
333 :
334 12 : sal_Int32 aPeriod = 2;
335 12 : CPPUNIT_ASSERT(xProperties->getPropertyValue("MovingAveragePeriod") >>= aPeriod);
336 12 : CPPUNIT_ASSERT_EQUAL(aExpectedPeriod, aPeriod);
337 12 : }
338 :
339 12 : void checkTrendlinesInChart(uno::Reference< chart2::XChartDocument > xChartDoc)
340 : {
341 12 : CPPUNIT_ASSERT(xChartDoc.is());
342 :
343 12 : Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 );
344 12 : CPPUNIT_ASSERT( xDataSeries.is() );
345 :
346 24 : Reference< chart2::XRegressionCurveContainer > xRegressionCurveContainer( xDataSeries, UNO_QUERY );
347 12 : CPPUNIT_ASSERT( xRegressionCurveContainer.is() );
348 :
349 24 : Sequence< Reference< chart2::XRegressionCurve > > xRegressionCurveSequence = xRegressionCurveContainer->getRegressionCurves();
350 12 : CPPUNIT_ASSERT_EQUAL((sal_Int32) 3, xRegressionCurveSequence.getLength());
351 :
352 24 : Reference<chart2::XRegressionCurve> xCurve;
353 :
354 12 : xCurve = xRegressionCurveSequence[0];
355 12 : CPPUNIT_ASSERT(xCurve.is());
356 12 : checkPolynomialTrendline(xCurve, "col2_poly", 3, 0.1, -0.1, true, -1.0, true, true);
357 :
358 12 : xCurve = xRegressionCurveSequence[1];
359 12 : CPPUNIT_ASSERT(xCurve.is());
360 12 : checkLinearTrendline(xCurve, "col2_linear", -0.5, -0.5, false, 0.0, true, false);
361 :
362 12 : xCurve = xRegressionCurveSequence[2];
363 12 : CPPUNIT_ASSERT(xCurve.is());
364 24 : checkMovingAverageTrendline(xCurve, "col2_moving_avg", 3);
365 12 : }
366 :
367 : }
368 :
369 : // improve the test
370 2 : void Chart2ExportTest::testErrorBarXLSX()
371 : {
372 2 : load("/chart2/qa/extras/data/ods/", "error_bar.ods");
373 : {
374 : // make sure the ODS import was successful
375 2 : uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent );
376 2 : CPPUNIT_ASSERT(xChartDoc.is());
377 :
378 4 : Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 );
379 2 : CPPUNIT_ASSERT( xDataSeries.is() );
380 :
381 4 : Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW );
382 2 : CPPUNIT_ASSERT( xPropSet.is() );
383 :
384 : // test that y error bars are there
385 4 : Reference< beans::XPropertySet > xErrorBarYProps;
386 2 : xPropSet->getPropertyValue(CHART_UNONAME_ERRORBAR_Y) >>= xErrorBarYProps;
387 4 : testErrorBar(xErrorBarYProps);
388 : }
389 :
390 2 : reload("Calc Office Open XML");
391 : {
392 2 : uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent );
393 2 : CPPUNIT_ASSERT(xChartDoc.is());
394 :
395 4 : Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 );
396 2 : CPPUNIT_ASSERT( xDataSeries.is() );
397 :
398 4 : Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW );
399 2 : CPPUNIT_ASSERT( xPropSet.is() );
400 :
401 : // test that y error bars are there
402 4 : Reference< beans::XPropertySet > xErrorBarYProps;
403 2 : xPropSet->getPropertyValue(CHART_UNONAME_ERRORBAR_Y) >>= xErrorBarYProps;
404 4 : testErrorBar(xErrorBarYProps);
405 : }
406 2 : }
407 :
408 : // This method tests the preservation of properties for trendlines / regression curves
409 : // in an export -> import cycle using different file formats - ODS, XLS and XLSX.
410 2 : void Chart2ExportTest::testTrendline()
411 : {
412 2 : mbSkipValidation = true;
413 2 : load("/chart2/qa/extras/data/ods/", "trendline.ods");
414 2 : checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent));
415 2 : reload("calc8");
416 2 : checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent));
417 2 : }
418 :
419 2 : void Chart2ExportTest::testTrendlineOOXML()
420 : {
421 2 : load("/chart2/qa/extras/data/ods/", "trendline.ods");
422 2 : checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent));
423 2 : reload("Calc Office Open XML");
424 2 : checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent));
425 2 : }
426 :
427 2 : void Chart2ExportTest::testTrendlineXLS()
428 : {
429 2 : load("/chart2/qa/extras/data/ods/", "trendline.ods");
430 2 : checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent));
431 2 : reload("MS Excel 97");
432 2 : checkTrendlinesInChart(getChartDocFromSheet( 0, mxComponent));
433 2 : }
434 :
435 2 : void Chart2ExportTest::testStockChart()
436 : {
437 : /* For attached file Stock_Chart.docx, in chart1.xml,
438 : * <c:stockChart>, there are four types of series as
439 : * Open,Low,High and Close.
440 : * For Open series, in <c:idx val="0" />
441 : * an attribute val of index should start from 1 and not from 0.
442 : * Which was problem area.
443 : */
444 2 : load("/chart2/qa/extras/data/docx/", "testStockChart.docx");
445 :
446 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
447 2 : if (!pXmlDoc)
448 2 : return;
449 :
450 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:stockChart/c:ser[1]/c:idx", "val", "1");
451 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:stockChart/c:ser[1]/c:order", "val", "1");
452 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:stockChart/c:ser[1]/c:tx/c:strRef/c:strCache/c:pt/c:v", "Open");
453 : }
454 :
455 2 : void Chart2ExportTest::testBarChart()
456 : {
457 2 : load("/chart2/qa/extras/data/docx/", "testBarChart.docx");
458 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
459 2 : if (!pXmlDoc)
460 2 : return;
461 :
462 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:barDir", "val", "col");
463 : }
464 :
465 2 : void Chart2ExportTest::testCrosses()
466 : {
467 2 : load("/chart2/qa/extras/data/docx/", "Bar_horizontal_cone.docx");
468 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
469 :
470 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:catAx/c:crosses", "val", "autoZero");
471 2 : }
472 :
473 2 : void Chart2ExportTest::testScatterChartTextXValues()
474 : {
475 2 : load("/chart2/qa/extras/data/docx/", "scatter-chart-text-x-values.docx");
476 :
477 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
478 2 : CPPUNIT_ASSERT(xChartDoc.is());
479 :
480 4 : Reference<chart2::XChartType> xCT = getChartTypeFromDoc(xChartDoc, 0, 0);
481 2 : CPPUNIT_ASSERT(xCT.is());
482 :
483 : // Make sure we have exactly 3 data series.
484 4 : std::vector<uno::Sequence<uno::Any> > aLabels = getDataSeriesLabelsFromChartType(xCT);
485 2 : CPPUNIT_ASSERT_EQUAL(size_t(3), aLabels.size());
486 2 : CPPUNIT_ASSERT_EQUAL(OUString("Series 1"), aLabels[0][0].get<OUString>());
487 2 : CPPUNIT_ASSERT_EQUAL(OUString("Series 2"), aLabels[1][0].get<OUString>());
488 2 : CPPUNIT_ASSERT_EQUAL(OUString("Series 3"), aLabels[2][0].get<OUString>());
489 :
490 4 : std::vector<std::vector<double> > aYValues = getDataSeriesYValuesFromChartType(xCT);
491 2 : CPPUNIT_ASSERT_EQUAL(size_t(3), aYValues.size());
492 :
493 : // Check the Y values of "Series 1".
494 2 : CPPUNIT_ASSERT_EQUAL(size_t(4), aYValues[0].size());
495 2 : CPPUNIT_ASSERT_EQUAL(4.3, aYValues[0][0]);
496 2 : CPPUNIT_ASSERT_EQUAL(2.5, aYValues[0][1]);
497 2 : CPPUNIT_ASSERT_EQUAL(3.5, aYValues[0][2]);
498 2 : CPPUNIT_ASSERT_EQUAL(4.5, aYValues[0][3]);
499 :
500 : // And "Series 2".
501 2 : CPPUNIT_ASSERT_EQUAL(size_t(4), aYValues[1].size());
502 2 : CPPUNIT_ASSERT_EQUAL(2.4, aYValues[1][0]);
503 2 : CPPUNIT_ASSERT_EQUAL(4.4, aYValues[1][1]);
504 2 : CPPUNIT_ASSERT_EQUAL(1.8, aYValues[1][2]);
505 2 : CPPUNIT_ASSERT_EQUAL(2.8, aYValues[1][3]);
506 :
507 : // And "Series 3".
508 2 : CPPUNIT_ASSERT_EQUAL(size_t(4), aYValues[2].size());
509 2 : CPPUNIT_ASSERT_EQUAL(2.0, aYValues[2][0]);
510 2 : CPPUNIT_ASSERT_EQUAL(2.0, aYValues[2][1]);
511 2 : CPPUNIT_ASSERT_EQUAL(3.0, aYValues[2][2]);
512 2 : CPPUNIT_ASSERT_EQUAL(5.0, aYValues[2][3]);
513 :
514 : // Test the export.
515 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
516 2 : if (!pXmlDoc)
517 2 : return;
518 :
519 4 : assertXPathContent(pXmlDoc, "//c:scatterChart/c:ser[1]/c:xVal[1]/c:numRef[1]/c:numCache[1]/c:pt[1]/c:v[1]", "1");
520 : }
521 :
522 2 : void Chart2ExportTest::testChartDataTable()
523 : {
524 2 : load("/chart2/qa/extras/data/docx/", "testChartDataTable.docx");
525 :
526 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
527 2 : CPPUNIT_ASSERT(pXmlDoc);
528 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:dTable/c:showHorzBorder", "val", "1");
529 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:dTable/c:showVertBorder", "val", "1");
530 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:dTable/c:showOutline", "val", "1");
531 2 : }
532 :
533 2 : void Chart2ExportTest::testChartExternalData()
534 : {
535 2 : load("/chart2/qa/extras/data/docx/", "testMultipleChart.docx");
536 :
537 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
538 2 : CPPUNIT_ASSERT(pXmlDoc);
539 2 : xmlXPathObjectPtr pXmlPathObj = getXPathNode(pXmlDoc, "/c:chartSpace/c:externalData");
540 2 : xmlNodeSetPtr pXmlNodes = pXmlPathObj->nodesetval;
541 2 : CPPUNIT_ASSERT(pXmlNodes);
542 2 : }
543 :
544 2 : void Chart2ExportTest::testEmbeddingsGrabBag()
545 : {
546 : // The problem was that .xlsx files were missing from docx file from embeddings folder
547 : // after saving file.
548 : // This test case tests whether embeddings files grabbagged properly in correct object.
549 :
550 2 : load("/chart2/qa/extras/data/docx/", "testMultiplechartembeddings.docx" );
551 2 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
552 4 : uno::Reference<beans::XPropertySet> xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY);
553 4 : uno::Sequence<beans::PropertyValue> aGrabBag(0);
554 2 : xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag;
555 2 : CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
556 2 : bool bEmbeddings = false;
557 : const char* testEmbeddedFileNames[3] = {"word/embeddings/Microsoft_Excel_Worksheet3.xlsx",
558 : "word/embeddings/Microsoft_Excel_Worksheet2.xlsx",
559 2 : "word/embeddings/Microsoft_Excel_Worksheet1.xlsx"};
560 26 : for(int i = 0; i < aGrabBag.getLength(); ++i)
561 : {
562 24 : if (aGrabBag[i].Name == "OOXEmbeddings")
563 : {
564 2 : bEmbeddings = true;
565 2 : uno::Sequence<beans::PropertyValue> aEmbeddingsList(0);
566 4 : uno::Reference<io::XInputStream> aEmbeddingXlsxStream;
567 4 : OUString aEmbeddedfileName;
568 2 : CPPUNIT_ASSERT(aGrabBag[i].Value >>= aEmbeddingsList); // PropertyValue of proper type
569 2 : sal_Int32 length = aEmbeddingsList.getLength();
570 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(3), length);
571 8 : for(int j = 0; j < length; ++j)
572 : {
573 6 : aEmbeddingsList[j].Value >>= aEmbeddingXlsxStream;
574 6 : aEmbeddedfileName = aEmbeddingsList[j].Name;
575 6 : CPPUNIT_ASSERT(aEmbeddingXlsxStream.get()); // Reference not empty
576 6 : CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(testEmbeddedFileNames[j]),aEmbeddedfileName);
577 2 : }
578 : }
579 : }
580 4 : CPPUNIT_ASSERT(bEmbeddings); // Grab Bag has all the expected elements
581 2 : }
582 :
583 2 : void Chart2ExportTest::testAreaChartLoad()
584 : {
585 2 : load ("/chart2/qa/extras/data/docx/", "testAreaChartLoad.docx");
586 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
587 2 : CPPUNIT_ASSERT(pXmlDoc);
588 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:areaChart/c:ser/c:dLbls/c:showVal", "val", "1");
589 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:areaChart/c:ser/c:dLbls/c:dLbl", 0);
590 2 : }
591 :
592 2 : void Chart2ExportTest::testUpDownBars()
593 : {
594 2 : load("/chart2/qa/extras/data/docx/", "UpDownBars.docx");
595 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
596 2 : CPPUNIT_ASSERT(pXmlDoc);
597 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:upDownBars");
598 2 : }
599 :
600 2 : void Chart2ExportTest::testDoughnutChart()
601 : {
602 2 : load("/chart2/qa/extras/data/docx/", "doughnutChart.docx");
603 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
604 2 : CPPUNIT_ASSERT(pXmlDoc);
605 :
606 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:doughnutChart", "1");
607 2 : }
608 :
609 2 : void Chart2ExportTest::testDisplayUnits()
610 : {
611 2 : load("/chart2/qa/extras/data/docx/", "DisplayUnits.docx");
612 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
613 2 : CPPUNIT_ASSERT(pXmlDoc);
614 :
615 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx/c:dispUnits/c:builtInUnit", "val", "billions");
616 2 : }
617 :
618 : // void Chart2ExportTest::testFdo74115WallGradientFill()
619 : // {
620 : // load("/chart2/qa/extras/data/docx/", "fdo74115_WallGradientFill.docx");
621 : // xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
622 : // CPPUNIT_ASSERT(pXmlDoc);
623 : //
624 : // assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:spPr/a:gradFill");
625 : // }
626 :
627 2 : void Chart2ExportTest::testFdo74115WallBitmapFill()
628 : {
629 2 : load("/chart2/qa/extras/data/docx/", "fdo74115_WallBitmapFill.docx");
630 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
631 2 : CPPUNIT_ASSERT(pXmlDoc);
632 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:spPr/a:blipFill");
633 2 : }
634 :
635 : //The below test case tests the built in marker 'x' for Office 2010 in Line charts
636 :
637 2 : void Chart2ExportTest::testFdo78290LineChartMarkerX()
638 : {
639 2 : load("/chart2/qa/extras/data/docx/", "fdo78290_Line_Chart_Marker_x.docx");
640 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
641 2 : CPPUNIT_ASSERT(pXmlDoc);
642 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:marker[1]/c:symbol[1]","val","x");
643 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:marker[1]/c:size[1]","val","7");
644 2 : }
645 :
646 : // We can also use the built in marker 'x' in scatter chart, hence writing the test case for the same.
647 :
648 2 : void Chart2ExportTest::testFdo78290ScatterChartMarkerX()
649 : {
650 2 : load("/chart2/qa/extras/data/docx/", "fdo78290_Scatter_Chart_Marker_x.docx");
651 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
652 2 : CPPUNIT_ASSERT(pXmlDoc);
653 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:scatterChart[1]/c:ser[1]/c:marker[1]/c:symbol[1]","val","x");
654 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:scatterChart[1]/c:ser[1]/c:marker[1]/c:size[1]","val","7");
655 2 : }
656 :
657 : // Also in a combination of charts like a column chart and line chart, we can use the built in marker 'x'
658 : // for the line chart too. hence put a test case for the combination chart also.
659 :
660 2 : void Chart2ExportTest::testFdo78290CombinationChartMarkerX()
661 : {
662 2 : load("/chart2/qa/extras/data/docx/", "fdo78290_Combination_Chart_Marker_x.docx");
663 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
664 2 : CPPUNIT_ASSERT(pXmlDoc);
665 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:marker[1]/c:symbol[1]","val","x");
666 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:marker[1]/c:size[1]","val","7");
667 2 : }
668 :
669 2 : void Chart2ExportTest::testAxisNumberFormatODS()
670 : {
671 : struct
672 : {
673 4 : void check( const Reference<chart2::XChartDocument>& xChartDoc )
674 : {
675 4 : Reference<chart2::XAxis> xAxisX = getAxisFromDoc(xChartDoc, 0, 0, 0);
676 8 : Reference<chart2::XTitled> xTitle(xAxisX, UNO_QUERY_THROW);
677 8 : OUString aTitleText = getTitleString(xTitle);
678 4 : CPPUNIT_ASSERT_EQUAL(OUString("Linked To Source"), aTitleText);
679 :
680 4 : sal_Int32 nNumFmt = getNumberFormatFromAxis(xAxisX);
681 4 : sal_Int16 nType = getNumberFormatType(xChartDoc, nNumFmt);
682 4 : CPPUNIT_ASSERT_MESSAGE("X axis should be percentage format.", (nType & util::NumberFormat::PERCENT));
683 :
684 4 : bool bNumFmtLinked = false;
685 8 : Reference<beans::XPropertySet> xPS(xAxisX, uno::UNO_QUERY_THROW);
686 4 : xPS->getPropertyValue("LinkNumberFormatToSource") >>= bNumFmtLinked;
687 4 : CPPUNIT_ASSERT_MESSAGE("X axis should have its number format linked to source.", bNumFmtLinked);
688 :
689 8 : Reference<chart2::XAxis> xAxisY = getAxisFromDoc(xChartDoc, 0, 1, 0);
690 4 : xTitle.set(xAxisY, UNO_QUERY_THROW);
691 4 : aTitleText = getTitleString(xTitle);
692 4 : CPPUNIT_ASSERT_EQUAL(OUString("Not Linked"), aTitleText);
693 :
694 4 : nNumFmt = getNumberFormatFromAxis(xAxisY);
695 4 : nType = getNumberFormatType(xChartDoc, nNumFmt);
696 4 : CPPUNIT_ASSERT_MESSAGE("Y axis should be a normal number format.", (nType & util::NumberFormat::NUMBER));
697 :
698 4 : bNumFmtLinked = true;
699 4 : xPS.set(xAxisY, uno::UNO_QUERY_THROW);
700 4 : xPS->getPropertyValue("LinkNumberFormatToSource") >>= bNumFmtLinked;
701 8 : CPPUNIT_ASSERT_MESSAGE("Y axis should not have its number format linked to source.", !bNumFmtLinked);
702 4 : }
703 :
704 : } aTest;
705 :
706 2 : load("/chart2/qa/extras/data/ods/", "axis-numformats-linked.ods");
707 :
708 2 : Reference<chart2::XChartDocument> xChartDoc = getChartDocFromSheet(0, mxComponent);
709 2 : aTest.check(xChartDoc);
710 :
711 : // Reload the document and make sure everything remains intact.
712 2 : reload("calc8");
713 2 : xChartDoc = getChartDocFromSheet(0, mxComponent);
714 2 : aTest.check(xChartDoc);
715 2 : }
716 :
717 2 : void Chart2ExportTest::testDataLabelBordersDOCX()
718 : {
719 : struct Check
720 : {
721 : sal_Int32 mnIndex;
722 : css::drawing::LineStyle meStyle;
723 : sal_Int32 mnColor;
724 : };
725 :
726 : struct
727 : {
728 : /**
729 : * Chart 1 has 4 bars of which 1st and 3rd have labels with borders
730 : * around them.
731 : */
732 4 : void checkObject1( const Reference<chart2::XChartDocument>& xChartDoc )
733 : {
734 4 : CPPUNIT_ASSERT(xChartDoc.is());
735 :
736 4 : Reference<chart2::XDataSeries> xDataSeries = getDataSeriesFromDoc(xChartDoc, 0);
737 4 : CPPUNIT_ASSERT(xDataSeries.is());
738 :
739 : // Check to make sure that data points 0 and 2 have local properties.
740 8 : Reference<beans::XPropertySet> xPropSet(xDataSeries, uno::UNO_QUERY);
741 4 : CPPUNIT_ASSERT(xPropSet.is());
742 :
743 8 : Sequence<sal_Int32> aIndices;
744 4 : xPropSet->getPropertyValue("AttributedDataPoints") >>= aIndices;
745 4 : CPPUNIT_ASSERT_MESSAGE("There should be 2 data points with local properties.", aIndices.getLength() == 2);
746 4 : CPPUNIT_ASSERT(aIndices[0] == 0);
747 4 : CPPUNIT_ASSERT(aIndices[1] == 2);
748 :
749 : const Check aDataPoints[] =
750 : {
751 : { 0, css::drawing::LineStyle_SOLID, 0x00FFFF00 }, // solid yellow
752 : { 2, css::drawing::LineStyle_SOLID, 0x00FF0000 } // solid red
753 4 : };
754 :
755 12 : for (size_t i = 0, n = SAL_N_ELEMENTS(aDataPoints); i < n; ++i)
756 : {
757 8 : xPropSet = xDataSeries->getDataPointByIndex(aDataPoints[i].mnIndex);
758 8 : CPPUNIT_ASSERT(xPropSet.is());
759 :
760 8 : css::drawing::LineStyle eLineStyle = css::drawing::LineStyle_NONE;
761 8 : xPropSet->getPropertyValue(CHART_UNONAME_LABEL_BORDER_STYLE) >>= eLineStyle;
762 8 : CPPUNIT_ASSERT(eLineStyle == aDataPoints[i].meStyle);
763 :
764 8 : sal_Int32 nWidth = -1;
765 8 : xPropSet->getPropertyValue(CHART_UNONAME_LABEL_BORDER_WIDTH) >>= nWidth;
766 8 : CPPUNIT_ASSERT(nWidth > 0);
767 :
768 8 : sal_Int32 nColor = -1;
769 8 : xPropSet->getPropertyValue(CHART_UNONAME_LABEL_BORDER_COLOR) >>= nColor;
770 8 : CPPUNIT_ASSERT_MESSAGE("Border color is wrong.", nColor == aDataPoints[i].mnColor);
771 4 : }
772 4 : }
773 :
774 : /**
775 : * Chart 2 has all its data labels with identical borders.
776 : */
777 4 : void checkObject2( const Reference<chart2::XChartDocument>& xChartDoc )
778 : {
779 4 : CPPUNIT_ASSERT(xChartDoc.is());
780 :
781 4 : Reference<chart2::XDataSeries> xDataSeries = getDataSeriesFromDoc(xChartDoc, 0);
782 4 : CPPUNIT_ASSERT(xDataSeries.is());
783 :
784 8 : Reference<beans::XPropertySet> xPropSet(xDataSeries, uno::UNO_QUERY);
785 4 : CPPUNIT_ASSERT(xPropSet.is());
786 :
787 4 : css::drawing::LineStyle eLineStyle = css::drawing::LineStyle_NONE;
788 4 : xPropSet->getPropertyValue(CHART_UNONAME_LABEL_BORDER_STYLE) >>= eLineStyle;
789 4 : CPPUNIT_ASSERT(eLineStyle == css::drawing::LineStyle_SOLID);
790 :
791 4 : sal_Int32 nWidth = -1;
792 4 : xPropSet->getPropertyValue(CHART_UNONAME_LABEL_BORDER_WIDTH) >>= nWidth;
793 4 : CPPUNIT_ASSERT(nWidth > 0);
794 :
795 4 : sal_Int32 nColor = -1;
796 4 : xPropSet->getPropertyValue(CHART_UNONAME_LABEL_BORDER_COLOR) >>= nColor;
797 8 : CPPUNIT_ASSERT_MESSAGE("Border color should be green.", nColor == 0x0000FF00);
798 4 : }
799 :
800 : } aTest;
801 :
802 2 : load("/chart2/qa/extras/data/docx/", "data-label-borders.docx");
803 :
804 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
805 :
806 : // "Automatic" chart background fill in docx should be loaded as solid white.
807 4 : Reference<beans::XPropertySet> xPropSet = xChartDoc->getPageBackground();
808 2 : CPPUNIT_ASSERT(xPropSet.is());
809 2 : drawing::FillStyle eStyle = xPropSet->getPropertyValue("FillStyle").get<drawing::FillStyle>();
810 2 : sal_Int32 nColor = xPropSet->getPropertyValue("FillColor").get<sal_Int32>();
811 4 : CPPUNIT_ASSERT_MESSAGE("'Automatic' chart background fill in docx should be loaded as solid fill.",
812 2 : eStyle == drawing::FillStyle_SOLID);
813 4 : CPPUNIT_ASSERT_MESSAGE("'Automatic' chart background fill in docx should be loaded as solid white.",
814 2 : (nColor & 0x00FFFFFF) == 0x00FFFFFF); // highest 2 bytes are transparency which we ignore here.
815 :
816 2 : aTest.checkObject1(xChartDoc);
817 2 : xChartDoc.set(getChartDocFromWriter(1), uno::UNO_QUERY);
818 2 : aTest.checkObject2(xChartDoc);
819 :
820 2 : reload("Office Open XML Text");
821 :
822 2 : xChartDoc.set(getChartDocFromWriter(0), uno::UNO_QUERY);
823 2 : aTest.checkObject1(xChartDoc);
824 2 : xChartDoc.set(getChartDocFromWriter(1), uno::UNO_QUERY);
825 4 : aTest.checkObject2(xChartDoc);
826 2 : }
827 :
828 2 : void Chart2ExportTest::testDataLabel3DChartDOCX()
829 : {
830 2 : load("/chart2/qa/extras/data/docx/", "3d-bar-label.docx");
831 :
832 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
833 2 : CPPUNIT_ASSERT(xChartDoc.is());
834 :
835 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
836 2 : CPPUNIT_ASSERT(pXmlDoc);
837 :
838 : // We must not export label position attributes for 3D bar charts. The
839 : // same rule also applies to several other 3D charts, apparently.
840 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:bar3DChart/c:ser/c:dLbls/c:dLblPos", 0);
841 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:bar3DChart/c:ser/c:dLbls/c:dLbl/c:dLblPos", 0);
842 2 : }
843 :
844 2 : void Chart2ExportTest::testDataLabelBarChartDOCX()
845 : {
846 2 : load("/chart2/qa/extras/data/docx/", "bar-chart-labels.docx");
847 :
848 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
849 2 : CPPUNIT_ASSERT(xChartDoc.is());
850 :
851 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
852 2 : CPPUNIT_ASSERT(pXmlDoc);
853 :
854 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:dLbls/c:dLblPos", "val", "ctr");
855 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[2]/c:dLbls/c:dLblPos", "val", "inEnd");
856 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[3]/c:dLbls/c:dLblPos", "val", "inBase");
857 2 : }
858 :
859 2 : void Chart2ExportTest::testDataLabelClusteredBarChartDOCX()
860 : {
861 2 : load("/chart2/qa/extras/data/docx/", "clustered-bar-chart-labels.docx");
862 :
863 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
864 2 : CPPUNIT_ASSERT(xChartDoc.is());
865 :
866 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
867 2 : CPPUNIT_ASSERT(pXmlDoc);
868 :
869 : // This was "t", should be one of the allowed values.
870 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:dLbls/c:dLbl[2]/c:dLblPos", "val", "ctr");
871 2 : }
872 :
873 2 : void Chart2ExportTest::testDataLabelRadarChartDOCX()
874 : {
875 2 : load("/chart2/qa/extras/data/docx/", "radar-chart-labels.docx");
876 :
877 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
878 2 : CPPUNIT_ASSERT(xChartDoc.is());
879 :
880 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
881 2 : CPPUNIT_ASSERT(pXmlDoc);
882 :
883 : // We must not export label position attributes for radar charts.
884 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:radarChart/c:ser/c:dLbls/c:dLblPos", 0);
885 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:radarChart/c:ser/c:dLbls/c:dLbl/c:dLblPos", 0);
886 2 : }
887 :
888 2 : void Chart2ExportTest::testDataLabelDoughnutChartDOCX()
889 : {
890 2 : load("/chart2/qa/extras/data/docx/", "doughnut-chart-labels.docx");
891 :
892 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
893 2 : CPPUNIT_ASSERT(xChartDoc.is());
894 :
895 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
896 2 : CPPUNIT_ASSERT(pXmlDoc);
897 :
898 : // We must not export label position attributes for doughnut charts.
899 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:doughnutChart/c:ser/c:dLbls/c:dLblPos", 0);
900 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:doughnutChart/c:ser/c:dLbls/c:dLbl/c:dLblPos", 0);
901 2 : }
902 :
903 2 : void Chart2ExportTest::testDataLabelAreaChartDOCX()
904 : {
905 2 : load("/chart2/qa/extras/data/docx/", "area-chart-labels.docx");
906 :
907 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
908 2 : CPPUNIT_ASSERT(xChartDoc.is());
909 :
910 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
911 2 : CPPUNIT_ASSERT(pXmlDoc);
912 :
913 : // We must not export label position attributes for area charts.
914 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:areaChart/c:ser/c:dLbls/c:dLblPos", 0);
915 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:areaChart/c:ser/c:dLbls/c:dLbl/c:dLblPos", 0);
916 2 : }
917 :
918 2 : void Chart2ExportTest::testDataLabelDefaultLineChartDOCX()
919 : {
920 : // This file was created by Word 2007, which doesn't provide default data
921 : // label position (2010 does). Make sure its default data label position
922 : // is RIGHT when exporting.
923 :
924 2 : load("/chart2/qa/extras/data/docx/", "line-chart-label-default-placement.docx");
925 :
926 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
927 2 : CPPUNIT_ASSERT(xChartDoc.is());
928 :
929 2 : reload("Office Open XML Text");
930 :
931 2 : xChartDoc.set(getChartDocFromWriter(0), uno::UNO_QUERY);
932 4 : Reference<chart2::XDataSeries> xDataSeries = getDataSeriesFromDoc(xChartDoc, 0);
933 4 : Reference<beans::XPropertySet> xPropSet(xDataSeries, uno::UNO_QUERY);
934 2 : CPPUNIT_ASSERT(xPropSet.is());
935 2 : sal_Int32 nLabelPlacement = -1;
936 2 : if (xPropSet->getPropertyValue("LabelPlacement") >>= nLabelPlacement)
937 : // This option may not be set. Check its value only when it's set.
938 4 : CPPUNIT_ASSERT_MESSAGE("Line chart's default label placement should be 'right'.", nLabelPlacement == chart::DataLabelPlacement::RIGHT);
939 2 : }
940 :
941 2 : void Chart2ExportTest::testBarChartRotation()
942 : {
943 2 : load ("/chart2/qa/extras/data/docx/", "barChartRotation.docx");
944 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
945 2 : CPPUNIT_ASSERT(pXmlDoc);
946 :
947 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotX", "val", "30");
948 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotY", "val", "50");
949 2 : }
950 :
951 2 : void Chart2ExportTest::testShapeFollowedByChart()
952 : {
953 : /* If there is a scenario where a chart is followed by a shape
954 : which is being exported as an alternate content then, the
955 : docPr Id is being repeated, ECMA 20.4.2.5 says that the
956 : docPr Id should be unique, ensuring the same here.
957 : */
958 2 : load("/chart2/qa/extras/data/docx/", "FDO74430.docx");
959 2 : xmlDocPtr pXmlDoc = parseExport("word/document", "Office Open XML Text" );
960 2 : CPPUNIT_ASSERT(pXmlDoc);
961 :
962 2 : OUString aValueOfFirstDocPR = getXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[1]/w:drawing[1]/wp:inline[1]/wp:docPr[1]", "id");
963 4 : OUString aValueOfSecondDocPR;
964 :
965 2 : aValueOfSecondDocPR = getXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/wp:docPr[1]", "id");
966 :
967 4 : CPPUNIT_ASSERT( aValueOfFirstDocPR != aValueOfSecondDocPR );
968 2 : }
969 :
970 2 : void Chart2ExportTest::testPieChartDataLabels()
971 : {
972 2 : load("/chart2/qa/extras/data/docx/", "PieChartDataLabels.docx");
973 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
974 2 : CPPUNIT_ASSERT(pXmlDoc);
975 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:pie3DChart/c:ser[1]/c:dLbls/c:dLbl[1]/c:dLblPos", "val", "bestFit");
976 2 : }
977 :
978 2 : void Chart2ExportTest::testSeriesIdxOrder()
979 : {
980 2 : load("/chart2/qa/extras/data/docx/", "testSeriesIdxOrder.docx");
981 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
982 2 : CPPUNIT_ASSERT(pXmlDoc);
983 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:idx[1]", "val", "1");
984 2 : assertXPath(pXmlDoc, "/c:chartSpace[1]/c:chart[1]/c:plotArea[1]/c:lineChart[1]/c:ser[1]/c:order[1]", "val", "1");
985 2 : }
986 :
987 2 : void Chart2ExportTest::testScatterPlotLabels()
988 : {
989 2 : load("/chart2/qa/extras/data/odt/", "scatter-plot-labels.odt");
990 2 : Reference<chart2::XChartDocument> xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
991 2 : CPPUNIT_ASSERT(xChartDoc.is());
992 :
993 4 : Reference<chart2::XChartType> xCT = getChartTypeFromDoc(xChartDoc, 0, 0);
994 2 : CPPUNIT_ASSERT(xCT.is());
995 :
996 : // Make sure the original chart has 'a', 'b', 'c' as its data labels.
997 4 : std::vector<uno::Sequence<uno::Any> > aLabels = getDataSeriesLabelsFromChartType(xCT);
998 2 : CPPUNIT_ASSERT_EQUAL(size_t(3), aLabels.size());
999 2 : CPPUNIT_ASSERT_EQUAL(OUString("a"), aLabels[0][0].get<OUString>());
1000 2 : CPPUNIT_ASSERT_EQUAL(OUString("b"), aLabels[1][0].get<OUString>());
1001 2 : CPPUNIT_ASSERT_EQUAL(OUString("c"), aLabels[2][0].get<OUString>());
1002 :
1003 : // Reload the doc and check again. The labels should not change.
1004 2 : reload("writer8");
1005 :
1006 2 : xChartDoc.set(getChartDocFromWriter(0), uno::UNO_QUERY);
1007 2 : CPPUNIT_ASSERT(xChartDoc.is());
1008 :
1009 2 : xCT = getChartTypeFromDoc(xChartDoc, 0, 0);
1010 2 : CPPUNIT_ASSERT(xCT.is());
1011 :
1012 2 : aLabels = getDataSeriesLabelsFromChartType(xCT);
1013 2 : CPPUNIT_ASSERT_EQUAL(size_t(3), aLabels.size());
1014 2 : CPPUNIT_ASSERT_EQUAL(OUString("a"), aLabels[0][0].get<OUString>());
1015 2 : CPPUNIT_ASSERT_EQUAL(OUString("b"), aLabels[1][0].get<OUString>());
1016 4 : CPPUNIT_ASSERT_EQUAL(OUString("c"), aLabels[2][0].get<OUString>());
1017 2 : }
1018 :
1019 2 : void Chart2ExportTest::testErrorBarDataRangeODS()
1020 : {
1021 2 : load("/chart2/qa/extras/data/ods/", "ErrorBarRange.ods");
1022 2 : reload("calc8");
1023 :
1024 2 : uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent );
1025 2 : CPPUNIT_ASSERT(xChartDoc.is());
1026 :
1027 4 : Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, 0 );
1028 2 : CPPUNIT_ASSERT( xDataSeries.is() );
1029 :
1030 4 : Reference< beans::XPropertySet > xPropSet( xDataSeries, UNO_QUERY_THROW );
1031 2 : CPPUNIT_ASSERT( xPropSet.is() );
1032 :
1033 : // test that y error bars are there
1034 4 : Reference< beans::XPropertySet > xErrorBarYProps;
1035 2 : xPropSet->getPropertyValue(CHART_UNONAME_ERRORBAR_Y) >>= xErrorBarYProps;
1036 4 : uno::Any aAny = xErrorBarYProps->getPropertyValue("ErrorBarRangePositive");
1037 2 : CPPUNIT_ASSERT(aAny.hasValue());
1038 4 : OUString aPosRange;
1039 2 : aAny >>= aPosRange;
1040 2 : CPPUNIT_ASSERT_EQUAL(OUString("$Sheet1.$B$1:$B$3"), aPosRange);
1041 :
1042 2 : aAny = xErrorBarYProps->getPropertyValue("ErrorBarRangeNegative");
1043 2 : CPPUNIT_ASSERT(aAny.hasValue());
1044 4 : OUString aNegRange;
1045 2 : aAny >>= aNegRange;
1046 4 : CPPUNIT_ASSERT_EQUAL(OUString("$Sheet1.$C$1:$C$3"), aNegRange);
1047 2 : }
1048 :
1049 2 : void Chart2ExportTest::testChartCrash()
1050 : {
1051 2 : load("/chart2/qa/extras/data/docx/", "FDO75975.docx");
1052 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text");
1053 2 : CPPUNIT_ASSERT(pXmlDoc);
1054 2 : }
1055 :
1056 2 : void Chart2ExportTest::testPieChartRotation()
1057 : {
1058 2 : load ("/chart2/qa/extras/data/docx/", "pieChartRotation.docx");
1059 2 : xmlDocPtr pXmlDoc = parseExport("word/charts/chart","Office Open XML Text");
1060 2 : CPPUNIT_ASSERT(pXmlDoc);
1061 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotX", "val", "40");
1062 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotY", "val", "30");
1063 2 : }
1064 :
1065 2 : void Chart2ExportTest::testEmbeddingsOleObjectGrabBag()
1066 : {
1067 : // The problem was that .bin files were missing from docx file from embeddings folder
1068 : // after saving file.
1069 : // This test case tests whether embeddings files grabbagged properly in correct object.
1070 :
1071 2 : load("/chart2/qa/extras/data/docx/", "testchartoleobjectembeddings.docx" );
1072 2 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
1073 4 : uno::Reference<beans::XPropertySet> xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY);
1074 4 : uno::Sequence<beans::PropertyValue> aGrabBag(0);
1075 2 : xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag;
1076 2 : CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
1077 2 : bool bEmbeddings = false;
1078 2 : const char* testEmbeddedFileNames[1] = {"word/embeddings/oleObject1.bin"};
1079 26 : for(int i = 0; i < aGrabBag.getLength(); ++i)
1080 : {
1081 24 : if (aGrabBag[i].Name == "OOXEmbeddings")
1082 : {
1083 2 : bEmbeddings = true;
1084 2 : uno::Sequence<beans::PropertyValue> aEmbeddingsList(0);
1085 4 : uno::Reference<io::XInputStream> aEmbeddingXlsxStream;
1086 4 : OUString aEmbeddedfileName;
1087 2 : CPPUNIT_ASSERT(aGrabBag[i].Value >>= aEmbeddingsList); // PropertyValue of proper type
1088 2 : sal_Int32 length = aEmbeddingsList.getLength();
1089 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), length);
1090 4 : for(int j = 0; j < length; ++j)
1091 : {
1092 2 : aEmbeddingsList[j].Value >>= aEmbeddingXlsxStream;
1093 2 : aEmbeddedfileName = aEmbeddingsList[j].Name;
1094 2 : CPPUNIT_ASSERT(aEmbeddingXlsxStream.get()); // Reference not empty
1095 2 : CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(testEmbeddedFileNames[j]),aEmbeddedfileName);
1096 2 : }
1097 : }
1098 : }
1099 4 : CPPUNIT_ASSERT(bEmbeddings); // Grab Bag has all the expected elements
1100 2 : }
1101 :
1102 : namespace {
1103 :
1104 8 : void checkGapWidth(Reference<beans::XPropertySet> xPropSet, sal_Int32 nValue)
1105 : {
1106 8 : uno::Any aAny = xPropSet->getPropertyValue("GapwidthSequence");
1107 8 : CPPUNIT_ASSERT(aAny.hasValue());
1108 16 : uno::Sequence< sal_Int32 > aSequence;
1109 8 : aAny >>= aSequence;
1110 8 : CPPUNIT_ASSERT(aSequence.getLength());
1111 16 : CPPUNIT_ASSERT_EQUAL(nValue, aSequence[0]);
1112 8 : }
1113 :
1114 8 : void checkOverlap(Reference<beans::XPropertySet> xPropSet, sal_Int32 nValue)
1115 : {
1116 8 : uno::Any aAny = xPropSet->getPropertyValue("OverlapSequence");
1117 8 : CPPUNIT_ASSERT(aAny.hasValue());
1118 16 : uno::Sequence< sal_Int32 > aSequence;
1119 8 : aAny >>= aSequence;
1120 8 : CPPUNIT_ASSERT(aSequence.getLength());
1121 16 : CPPUNIT_ASSERT_EQUAL(nValue, aSequence[0]);
1122 8 : }
1123 :
1124 8 : void checkSheetForGapWidthAndOverlap(uno::Reference< chart2::XChartDocument > xChartDoc,
1125 : sal_Int32 nExpectedGapWidth, sal_Int32 nExpectedOverlap)
1126 : {
1127 8 : CPPUNIT_ASSERT(xChartDoc.is());
1128 :
1129 8 : Reference< chart2::XChartType > xChartType = getChartTypeFromDoc( xChartDoc, 0, 0 );
1130 8 : CPPUNIT_ASSERT(xChartType.is());
1131 :
1132 16 : Reference< beans::XPropertySet > xPropSet( xChartType, uno::UNO_QUERY_THROW );
1133 8 : checkGapWidth(xPropSet, nExpectedGapWidth);
1134 16 : checkOverlap(xPropSet, nExpectedOverlap);
1135 :
1136 8 : }
1137 :
1138 : }
1139 :
1140 2 : void Chart2ExportTest::testGapWidthXLSX()
1141 : {
1142 2 : load("/chart2/qa/extras/data/xlsx/", "gapWidth.xlsx");
1143 :
1144 2 : uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent );
1145 2 : checkSheetForGapWidthAndOverlap(xChartDoc, 120, -60);
1146 :
1147 2 : xChartDoc = getChartDocFromSheet( 1, mxComponent );
1148 2 : checkSheetForGapWidthAndOverlap(xChartDoc, 50, 30);
1149 :
1150 2 : reload("Calc Office Open XML");
1151 :
1152 2 : xChartDoc = getChartDocFromSheet( 0, mxComponent );
1153 2 : checkSheetForGapWidthAndOverlap(xChartDoc, 120, -60);
1154 :
1155 2 : xChartDoc = getChartDocFromSheet( 1, mxComponent );
1156 2 : checkSheetForGapWidthAndOverlap(xChartDoc, 50, 30);
1157 2 : }
1158 :
1159 2 : void Chart2ExportTest::testSmoothedLines()
1160 : {
1161 2 : load("/chart2/qa/extras/data/ods/", "smoothedLines.ods");
1162 2 : xmlDocPtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML");
1163 2 : CPPUNIT_ASSERT(pXmlDoc);
1164 2 : assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser[1]/c:smooth", "val", "0");
1165 2 : }
1166 :
1167 2 : void Chart2ExportTest::testLabelStringODS()
1168 : {
1169 2 : load("/chart2/qa/extras/data/ods/", "labelString.ods");
1170 :
1171 2 : uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet( 0, mxComponent );
1172 : Reference< chart2::data::XDataSequence > xLabelSeq =
1173 4 : getLabelDataSequenceFromDoc(xChartDoc);
1174 2 : CPPUNIT_ASSERT(xLabelSeq.is());
1175 :
1176 4 : OUString aLabelString = xLabelSeq->getSourceRangeRepresentation();
1177 2 : CPPUNIT_ASSERT_EQUAL(OUString("\"LabelName\""), aLabelString);
1178 :
1179 2 : reload("calc8");
1180 :
1181 2 : xChartDoc = getChartDocFromSheet( 0, mxComponent );
1182 2 : xLabelSeq = getLabelDataSequenceFromDoc(xChartDoc);
1183 2 : CPPUNIT_ASSERT(xLabelSeq.is());
1184 :
1185 2 : aLabelString = xLabelSeq->getSourceRangeRepresentation();
1186 4 : CPPUNIT_ASSERT_EQUAL(OUString("\"LabelName\""), aLabelString);
1187 2 : }
1188 :
1189 2 : CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest);
1190 :
1191 8 : CPPUNIT_PLUGIN_IMPLEMENT();
1192 :
1193 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|