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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <sax/tools/converter.hxx>
22 :
23 : #include "SchXMLPlotAreaContext.hxx"
24 : #include "SchXMLImport.hxx"
25 : #include "SchXMLAxisContext.hxx"
26 : #include "SchXMLSeries2Context.hxx"
27 : #include "SchXMLTools.hxx"
28 : #include <tools/debug.hxx>
29 :
30 : #include <comphelper/processfactory.hxx>
31 : #include "xmloff/xmlnmspe.hxx"
32 : #include <xmloff/xmlement.hxx>
33 : #include <xmloff/nmspmap.hxx>
34 : #include <xmloff/xmluconv.hxx>
35 : #include <xmloff/prstylei.hxx>
36 : #include <xmloff/xmlstyle.hxx>
37 : #include "xexptran.hxx"
38 : #include <cppuhelper/implbase1.hxx>
39 :
40 : #include <com/sun/star/awt/Point.hpp>
41 : #include <com/sun/star/awt/Size.hpp>
42 :
43 : #include <com/sun/star/chart/ChartDataRowSource.hpp>
44 : #include <com/sun/star/chart/ChartErrorCategory.hpp>
45 : #include <com/sun/star/chart/ChartErrorIndicatorType.hpp>
46 : #include <com/sun/star/chart/ErrorBarStyle.hpp>
47 : #include <com/sun/star/chart/X3DDisplay.hpp>
48 : #include <com/sun/star/chart/XStatisticDisplay.hpp>
49 : #include <com/sun/star/chart/XDiagramPositioning.hpp>
50 :
51 : #include <com/sun/star/chart2/data/XDataSink.hpp>
52 : #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
53 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
54 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
55 : #include <com/sun/star/chart2/RelativePosition.hpp>
56 :
57 : #include <com/sun/star/drawing/CameraGeometry.hpp>
58 : #include <com/sun/star/drawing/FillStyle.hpp>
59 : #include <com/sun/star/lang/XServiceInfo.hpp>
60 : #include <com/sun/star/util/XStringMapping.hpp>
61 : #include <com/sun/star/xml/sax/XAttributeList.hpp>
62 :
63 : using namespace com::sun::star;
64 : using namespace ::xmloff::token;
65 :
66 : using ::rtl::OUString;
67 : using com::sun::star::uno::Reference;
68 :
69 : namespace
70 : {
71 :
72 : struct lcl_AxisHasCategories : public ::std::unary_function< SchXMLAxis, bool >
73 : {
74 0 : bool operator() ( const SchXMLAxis & rAxis )
75 : {
76 0 : return rAxis.bHasCategories;
77 : }
78 : };
79 :
80 0 : OUString lcl_ConvertRange( const ::rtl::OUString & rRange, const uno::Reference< chart2::XChartDocument > & xDoc )
81 : {
82 0 : OUString aResult = rRange;
83 0 : if(!xDoc.is())
84 : return aResult;
85 : uno::Reference< chart2::data::XRangeXMLConversion > xConversion(
86 0 : xDoc->getDataProvider(), uno::UNO_QUERY );
87 0 : if( xConversion.is())
88 0 : aResult = xConversion->convertRangeFromXML( rRange );
89 0 : return aResult;
90 : }
91 :
92 : } // anonymous namespace
93 :
94 0 : SchXML3DSceneAttributesHelper::SchXML3DSceneAttributesHelper( SvXMLImport& rImporter )
95 0 : : SdXML3DSceneAttributesHelper( rImporter )
96 : {
97 0 : }
98 :
99 0 : void SchXML3DSceneAttributesHelper::getCameraDefaultFromDiagram( const uno::Reference< chart::XDiagram >& xDiagram )
100 : {
101 : //different defaults for camera geometry necessary to workaround wrong behaviour in old chart
102 : //in future make this version dependent if we have versioning (metastream) for ole objects
103 :
104 : try
105 : {
106 0 : uno::Reference< beans::XPropertySet > xProp( xDiagram, uno::UNO_QUERY );
107 0 : if( xProp.is() )
108 : {
109 0 : drawing::CameraGeometry aCamGeo;
110 0 : xProp->getPropertyValue( ::rtl::OUString( "D3DCameraGeometry" )) >>= aCamGeo;
111 0 : maVRP.setX( aCamGeo.vrp.PositionX );
112 0 : maVRP.setY( aCamGeo.vrp.PositionY );
113 0 : maVRP.setZ( aCamGeo.vrp.PositionZ );
114 0 : maVPN.setX( aCamGeo.vpn.DirectionX );
115 0 : maVPN.setY( aCamGeo.vpn.DirectionY );
116 0 : maVPN.setZ( aCamGeo.vpn.DirectionZ );
117 0 : maVUP.setX( aCamGeo.vup.DirectionX );
118 0 : maVUP.setY( aCamGeo.vup.DirectionY );
119 0 : maVUP.setZ( aCamGeo.vup.DirectionZ );
120 0 : }
121 : }
122 0 : catch( const uno::Exception & rEx )
123 : {
124 : #ifdef DBG_UTIL
125 : rtl::OString aBStr(rtl::OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
126 : OSL_TRACE( "Exception caught for property NumberOfLines: %s", aBStr.getStr());
127 : #else
128 : (void)rEx; // avoid warning for pro build
129 : #endif
130 : }
131 0 : }
132 :
133 0 : SchXML3DSceneAttributesHelper::~SchXML3DSceneAttributesHelper()
134 : {
135 0 : }
136 :
137 0 : SchXMLPlotAreaContext::SchXMLPlotAreaContext(
138 : SchXMLImportHelper& rImpHelper,
139 : SvXMLImport& rImport, const rtl::OUString& rLocalName,
140 : const rtl::OUString& rXLinkHRefAttributeToIndicateDataProvider,
141 : ::rtl::OUString& rCategoriesAddress,
142 : ::rtl::OUString& rChartAddress,
143 : bool& rbHasRangeAtPlotArea,
144 : sal_Bool & rAllRangeAddressesAvailable,
145 : sal_Bool & rColHasLabels,
146 : sal_Bool & rRowHasLabels,
147 : chart::ChartDataRowSource & rDataRowSource,
148 : SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles,
149 : const ::rtl::OUString& aChartTypeServiceName,
150 : tSchXMLLSequencesPerIndex & rLSequencesPerIndex,
151 : const awt::Size & rChartSize ) :
152 : SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
153 : mrImportHelper( rImpHelper ),
154 : mrCategoriesAddress( rCategoriesAddress ),
155 : mrSeriesDefaultsAndStyles( rSeriesDefaultsAndStyles ),
156 : mnNumOfLinesProp( 0 ),
157 : mbStockHasVolume( sal_False ),
158 : mnSeries( 0 ),
159 : m_aGlobalSeriesImportInfo( rAllRangeAddressesAvailable ),
160 : maSceneImportHelper( rImport ),
161 : m_aOuterPositioning( rImport ),
162 : m_aInnerPositioning( rImport ),
163 : mbPercentStacked(false),
164 : m_bAxisPositionAttributeImported(false),
165 : m_rXLinkHRefAttributeToIndicateDataProvider(rXLinkHRefAttributeToIndicateDataProvider),
166 : mrChartAddress( rChartAddress ),
167 : m_rbHasRangeAtPlotArea( rbHasRangeAtPlotArea ),
168 : mrColHasLabels( rColHasLabels ),
169 : mrRowHasLabels( rRowHasLabels ),
170 : mrDataRowSource( rDataRowSource ),
171 : maChartTypeServiceName( aChartTypeServiceName ),
172 : mrLSequencesPerIndex( rLSequencesPerIndex ),
173 : mbGlobalChartTypeUsedBySeries( false ),
174 0 : maChartSize( rChartSize )
175 : {
176 0 : m_rbHasRangeAtPlotArea = false;
177 :
178 : // get Diagram
179 0 : uno::Reference< chart::XChartDocument > xDoc( rImpHelper.GetChartDocument(), uno::UNO_QUERY );
180 0 : if( xDoc.is())
181 : {
182 0 : mxDiagram = xDoc->getDiagram();
183 0 : mxNewDoc.set( xDoc, uno::UNO_QUERY );
184 :
185 0 : maSceneImportHelper.getCameraDefaultFromDiagram( mxDiagram );
186 : }
187 : DBG_ASSERT( mxDiagram.is(), "Couldn't get XDiagram" );
188 :
189 : // turn off all axes initially
190 0 : uno::Any aFalseBool;
191 0 : aFalseBool <<= (sal_Bool)(sal_False);
192 :
193 0 : uno::Reference< lang::XServiceInfo > xInfo( mxDiagram, uno::UNO_QUERY );
194 0 : uno::Reference< beans::XPropertySet > xProp( mxDiagram, uno::UNO_QUERY );
195 0 : if( xInfo.is() &&
196 0 : xProp.is())
197 : {
198 : try
199 : {
200 0 : xProp->setPropertyValue(
201 0 : rtl::OUString( "HasXAxis" ), aFalseBool );
202 0 : xProp->setPropertyValue(
203 0 : rtl::OUString( "HasXAxisGrid" ), aFalseBool );
204 0 : xProp->setPropertyValue(
205 0 : rtl::OUString( "HasXAxisDescription" ), aFalseBool );
206 0 : xProp->setPropertyValue(
207 0 : rtl::OUString( "HasSecondaryXAxis" ), aFalseBool );
208 0 : xProp->setPropertyValue(
209 0 : rtl::OUString( "HasSecondaryXAxisDescription" ), aFalseBool );
210 :
211 0 : xProp->setPropertyValue(
212 0 : rtl::OUString( "HasYAxis" ), aFalseBool );
213 0 : xProp->setPropertyValue(
214 0 : rtl::OUString( "HasYAxisGrid" ), aFalseBool );
215 0 : xProp->setPropertyValue(
216 0 : rtl::OUString( "HasYAxisDescription" ), aFalseBool );
217 0 : xProp->setPropertyValue(
218 0 : rtl::OUString( "HasSecondaryYAxis" ), aFalseBool );
219 0 : xProp->setPropertyValue(
220 0 : rtl::OUString( "HasSecondaryYAxisDescription" ), aFalseBool );
221 :
222 0 : xProp->setPropertyValue(
223 0 : rtl::OUString( "HasZAxis" ), aFalseBool );
224 0 : xProp->setPropertyValue(
225 0 : rtl::OUString( "HasZAxisDescription" ), aFalseBool );
226 :
227 0 : uno::Any aAny;
228 0 : chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS;
229 0 : aAny <<= eSource;
230 0 : xProp->setPropertyValue( rtl::OUString( "DataRowSource" ), aAny );
231 : }
232 0 : catch( const beans::UnknownPropertyException & )
233 : {
234 : OSL_FAIL( "Property required by service not supported" );
235 : }
236 0 : }
237 0 : }
238 :
239 0 : SchXMLPlotAreaContext::~SchXMLPlotAreaContext()
240 0 : {}
241 :
242 0 : void SchXMLPlotAreaContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
243 : {
244 : // parse attributes
245 0 : sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
246 0 : const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetPlotAreaAttrTokenMap();
247 0 : uno::Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY );
248 :
249 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
250 : {
251 0 : rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
252 0 : rtl::OUString aLocalName;
253 0 : rtl::OUString aValue = xAttrList->getValueByIndex( i );
254 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
255 :
256 0 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
257 : {
258 : case XML_TOK_PA_X:
259 : case XML_TOK_PA_Y:
260 : case XML_TOK_PA_WIDTH:
261 : case XML_TOK_PA_HEIGHT:
262 0 : m_aOuterPositioning.readPositioningAttribute( nPrefix, aLocalName, aValue );
263 0 : break;
264 : case XML_TOK_PA_STYLE_NAME:
265 0 : msAutoStyleName = aValue;
266 0 : break;
267 : case XML_TOK_PA_CHART_ADDRESS:
268 0 : mrChartAddress = lcl_ConvertRange( aValue, xNewDoc );
269 : // indicator for getting data from the outside
270 0 : m_rbHasRangeAtPlotArea = true;
271 0 : break;
272 : case XML_TOK_PA_DS_HAS_LABELS:
273 : {
274 0 : if( aValue.equals( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_BOTH )))
275 0 : mrColHasLabels = mrRowHasLabels = sal_True;
276 0 : else if( aValue.equals( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_ROW )))
277 0 : mrRowHasLabels = sal_True;
278 0 : else if( aValue.equals( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_COLUMN )))
279 0 : mrColHasLabels = sal_True;
280 : }
281 0 : break;
282 : case XML_TOK_PA_TRANSFORM:
283 : case XML_TOK_PA_VRP:
284 : case XML_TOK_PA_VPN:
285 : case XML_TOK_PA_VUP:
286 : case XML_TOK_PA_PROJECTION:
287 : case XML_TOK_PA_DISTANCE:
288 : case XML_TOK_PA_FOCAL_LENGTH:
289 : case XML_TOK_PA_SHADOW_SLANT:
290 : case XML_TOK_PA_SHADE_MODE:
291 : case XML_TOK_PA_AMBIENT_COLOR:
292 : case XML_TOK_PA_LIGHTING_MODE:
293 0 : maSceneImportHelper.processSceneAttribute( nPrefix, aLocalName, aValue );
294 0 : break;
295 : }
296 0 : }
297 :
298 0 : if( ! mxNewDoc.is())
299 : {
300 0 : uno::Reference< beans::XPropertySet > xDocProp( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
301 0 : if( xDocProp.is())
302 : {
303 : try
304 : {
305 0 : uno::Any aAny;
306 0 : aAny <<= (sal_Bool)(mrColHasLabels);
307 0 : xDocProp->setPropertyValue(
308 : ::rtl::OUString( "DataSourceLabelsInFirstColumn" ),
309 0 : aAny );
310 :
311 0 : aAny <<= (sal_Bool)(mrRowHasLabels);
312 0 : xDocProp->setPropertyValue(
313 : ::rtl::OUString( "DataSourceLabelsInFirstRow" ),
314 0 : aAny );
315 : }
316 0 : catch( const beans::UnknownPropertyException & )
317 : {
318 : SAL_WARN( "xmloff.chart", "Properties missing" );
319 : }
320 0 : }
321 : }
322 :
323 : // set properties
324 0 : uno::Reference< beans::XPropertySet > xProp( mxDiagram, uno::UNO_QUERY );
325 0 : if( !msAutoStyleName.isEmpty())
326 : {
327 0 : if( xProp.is())
328 : {
329 0 : const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
330 0 : if( pStylesCtxt )
331 : {
332 : const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
333 0 : mrImportHelper.GetChartFamilyID(), msAutoStyleName );
334 :
335 : XMLPropStyleContext* pPropStyleContext =
336 : const_cast< XMLPropStyleContext * >(
337 0 : dynamic_cast< const XMLPropStyleContext * >( pStyle ) );
338 0 : if( pPropStyleContext )
339 : {
340 0 : pPropStyleContext->FillPropertySet( xProp );
341 :
342 : // get the data row source that was set without having data
343 0 : xProp->getPropertyValue( ::rtl::OUString( "DataRowSource" ))
344 0 : >>= mrDataRowSource;
345 :
346 : //lines on/off
347 : //this old property is not supported fully anymore with the new chart, so we need to get the information a little bit different from similar properties
348 : mrSeriesDefaultsAndStyles.maLinesOnProperty = SchXMLTools::getPropertyFromContext(
349 0 : ::rtl::OUString("Lines"), pPropStyleContext, pStylesCtxt );
350 :
351 : //handle automatic position and size
352 0 : m_aOuterPositioning.readAutomaticPositioningProperties( pPropStyleContext, pStylesCtxt );
353 :
354 : //correct default starting angle for old 3D pies
355 0 : if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan3_0( GetImport().GetModel() ) )
356 : {
357 0 : bool bIs3d = false;
358 0 : if( xProp.is() && ( xProp->getPropertyValue(::rtl::OUString("Dim3D")) >>= bIs3d ) &&
359 : bIs3d )
360 : {
361 0 : if( maChartTypeServiceName == "com.sun.star.chart2.PieChartType" || maChartTypeServiceName == "com.sun.star.chart2.DonutChartType" )
362 : {
363 0 : ::rtl::OUString aPropName( ::rtl::OUString("StartingAngle") );
364 0 : uno::Any aAStartingAngle( SchXMLTools::getPropertyFromContext( aPropName, pPropStyleContext, pStylesCtxt ) );
365 0 : if( !aAStartingAngle.hasValue() )
366 0 : xProp->setPropertyValue( aPropName, uno::makeAny(sal_Int32(0)) ) ;
367 : }
368 : }
369 : }
370 : }
371 : }
372 : }
373 : }
374 :
375 : //remember default values for dataseries
376 0 : if(xProp.is())
377 : try
378 : {
379 0 : mrSeriesDefaultsAndStyles.maSymbolTypeDefault = xProp->getPropertyValue(::rtl::OUString("SymbolType"));
380 0 : mrSeriesDefaultsAndStyles.maDataCaptionDefault = xProp->getPropertyValue(::rtl::OUString("DataCaption"));
381 :
382 0 : mrSeriesDefaultsAndStyles.maMeanValueDefault = xProp->getPropertyValue(::rtl::OUString("MeanValue"));
383 0 : mrSeriesDefaultsAndStyles.maRegressionCurvesDefault = xProp->getPropertyValue(::rtl::OUString("RegressionCurves"));
384 :
385 0 : bool bStacked = false;
386 0 : mrSeriesDefaultsAndStyles.maStackedDefault = xProp->getPropertyValue(::rtl::OUString("Stacked"));
387 0 : mrSeriesDefaultsAndStyles.maStackedDefault >>= bStacked;
388 0 : mrSeriesDefaultsAndStyles.maPercentDefault = xProp->getPropertyValue(::rtl::OUString("Percent"));
389 0 : mrSeriesDefaultsAndStyles.maPercentDefault >>= mbPercentStacked;
390 0 : mrSeriesDefaultsAndStyles.maStackedBarsConnectedDefault = xProp->getPropertyValue(::rtl::OUString("StackedBarsConnected"));
391 :
392 : // deep
393 0 : uno::Any aDeepProperty( xProp->getPropertyValue(::rtl::OUString("Deep")));
394 : // #124488# old versions store a 3d area and 3D line deep chart with Deep==false => workaround for this
395 0 : if( ! (bStacked || mbPercentStacked ))
396 : {
397 0 : if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) )
398 : {
399 0 : bool bIs3d = false;
400 0 : if( ( xProp->getPropertyValue(::rtl::OUString("Dim3D")) >>= bIs3d ) &&
401 : bIs3d )
402 : {
403 0 : if( maChartTypeServiceName == "com.sun.star.chart2.AreaChartType" || maChartTypeServiceName == "com.sun.star.chart2.LineChartType" )
404 : {
405 0 : aDeepProperty <<= uno::makeAny( true );
406 : }
407 : }
408 : }
409 : }
410 0 : mrSeriesDefaultsAndStyles.maDeepDefault = aDeepProperty;
411 :
412 0 : xProp->getPropertyValue(::rtl::OUString("NumberOfLines")) >>= mnNumOfLinesProp;
413 0 : xProp->getPropertyValue(::rtl::OUString("Volume")) >>= mbStockHasVolume;
414 : }
415 0 : catch( const uno::Exception & rEx )
416 : {
417 : #ifdef DBG_UTIL
418 : rtl::OString aBStr(rtl::OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
419 : OSL_TRACE("PlotAreaContext:EndElement(): Exception caught: %s", aBStr.getStr());
420 : #else
421 : (void)rEx; // avoid warning for pro build
422 : #endif
423 : }
424 : //
425 :
426 0 : bool bCreateInternalDataProvider = false;
427 0 : if( m_rXLinkHRefAttributeToIndicateDataProvider == "." ) //data comes from the chart itself
428 0 : bCreateInternalDataProvider = true;
429 0 : else if( m_rXLinkHRefAttributeToIndicateDataProvider == ".." ) //data comes from the parent application
430 0 : bCreateInternalDataProvider = false;
431 0 : else if( !m_rXLinkHRefAttributeToIndicateDataProvider.isEmpty() ) //not supported so far to get the data by sibling objects -> fall back to chart itself
432 0 : bCreateInternalDataProvider = true;
433 0 : else if( !m_rbHasRangeAtPlotArea )
434 0 : bCreateInternalDataProvider = true;
435 :
436 0 : if( bCreateInternalDataProvider && mxNewDoc.is() )
437 : {
438 : // we have no complete range => we have own data, so switch the data
439 : // provider to internal. Clone is not necessary, as we don't have any
440 : // data yet.
441 0 : mxNewDoc->createInternalDataProvider( false /* bCloneExistingData */ );
442 0 : if( xProp.is() && mrDataRowSource!=chart::ChartDataRowSource_COLUMNS )
443 0 : xProp->setPropertyValue( rtl::OUString( "DataRowSource" ), uno::makeAny(mrDataRowSource) );
444 0 : }
445 0 : }
446 :
447 0 : SvXMLImportContext* SchXMLPlotAreaContext::CreateChildContext(
448 : sal_uInt16 nPrefix,
449 : const rtl::OUString& rLocalName,
450 : const uno::Reference< xml::sax::XAttributeList >& xAttrList )
451 : {
452 0 : SvXMLImportContext* pContext = 0;
453 0 : const SvXMLTokenMap& rTokenMap = mrImportHelper.GetPlotAreaElemTokenMap();
454 :
455 0 : switch( rTokenMap.Get( nPrefix, rLocalName ))
456 : {
457 : case XML_TOK_PA_COORDINATE_REGION_EXT:
458 : case XML_TOK_PA_COORDINATE_REGION:
459 : {
460 0 : pContext = new SchXMLCoordinateRegionContext( GetImport(), nPrefix, rLocalName, m_aInnerPositioning );
461 : }
462 0 : break;
463 :
464 : case XML_TOK_PA_AXIS:
465 : {
466 0 : bool bAddMissingXAxisForNetCharts = false;
467 0 : bool bAdaptWrongPercentScaleValues = false;
468 0 : if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) )
469 : {
470 : //correct errors from older versions
471 :
472 : // for NetCharts there were no xAxis exported to older files
473 : // so we need to add the x axis here for those old NetChart files
474 0 : if ( maChartTypeServiceName == "com.sun.star.chart2.NetChartType" )
475 0 : bAddMissingXAxisForNetCharts = true;
476 :
477 : //Issue 59288
478 0 : if( mbPercentStacked )
479 0 : bAdaptWrongPercentScaleValues = true;
480 : }
481 :
482 0 : bool bAdaptXAxisOrientationForOld2DBarCharts = false;
483 0 : if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_4( GetImport().GetModel() ) )
484 : {
485 : //issue74660
486 0 : if ( maChartTypeServiceName == "com.sun.star.chart2.ColumnChartType" )
487 0 : bAdaptXAxisOrientationForOld2DBarCharts = true;
488 : }
489 :
490 0 : pContext = new SchXMLAxisContext( mrImportHelper, GetImport(), rLocalName, mxDiagram, maAxes, mrCategoriesAddress,
491 0 : bAddMissingXAxisForNetCharts, bAdaptWrongPercentScaleValues, bAdaptXAxisOrientationForOld2DBarCharts, m_bAxisPositionAttributeImported );
492 : }
493 0 : break;
494 :
495 : case XML_TOK_PA_SERIES:
496 : {
497 0 : if( mxNewDoc.is())
498 : {
499 : pContext = new SchXMLSeries2Context(
500 0 : mrImportHelper, GetImport(), rLocalName,
501 : mxNewDoc, maAxes,
502 : mrSeriesDefaultsAndStyles.maSeriesStyleList,
503 : mnSeries,
504 : mbStockHasVolume,
505 : m_aGlobalSeriesImportInfo,
506 : maChartTypeServiceName,
507 : mrLSequencesPerIndex,
508 0 : mbGlobalChartTypeUsedBySeries, maChartSize );
509 : }
510 0 : mnSeries++;
511 : }
512 0 : break;
513 :
514 : case XML_TOK_PA_WALL:
515 0 : pContext = new SchXMLWallFloorContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram,
516 0 : SchXMLWallFloorContext::CONTEXT_TYPE_WALL );
517 0 : break;
518 : case XML_TOK_PA_FLOOR:
519 0 : pContext = new SchXMLWallFloorContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram,
520 0 : SchXMLWallFloorContext::CONTEXT_TYPE_FLOOR );
521 0 : break;
522 :
523 : case XML_TOK_PA_LIGHT_SOURCE:
524 0 : pContext = maSceneImportHelper.create3DLightContext( nPrefix, rLocalName, xAttrList );
525 0 : break;
526 :
527 : // elements for stock charts
528 : case XML_TOK_PA_STOCK_GAIN:
529 0 : pContext = new SchXMLStockContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram,
530 0 : SchXMLStockContext::CONTEXT_TYPE_GAIN );
531 0 : break;
532 : case XML_TOK_PA_STOCK_LOSS:
533 0 : pContext = new SchXMLStockContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram,
534 0 : SchXMLStockContext::CONTEXT_TYPE_LOSS );
535 0 : break;
536 : case XML_TOK_PA_STOCK_RANGE:
537 0 : pContext = new SchXMLStockContext( mrImportHelper, GetImport(), nPrefix, rLocalName, mxDiagram,
538 0 : SchXMLStockContext::CONTEXT_TYPE_RANGE );
539 0 : break;
540 :
541 : default:
542 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
543 : }
544 :
545 0 : return pContext;
546 : }
547 :
548 0 : void SchXMLPlotAreaContext::EndElement()
549 : {
550 : // set categories
551 0 : if( !mrCategoriesAddress.isEmpty() && mxNewDoc.is())
552 : {
553 : uno::Reference< chart2::data::XDataProvider > xDataProvider(
554 0 : mxNewDoc->getDataProvider() );
555 : // @todo: correct coordinate system index
556 0 : sal_Int32 nDimension( 0 );
557 : ::std::vector< SchXMLAxis >::const_iterator aIt(
558 0 : ::std::find_if( maAxes.begin(), maAxes.end(), lcl_AxisHasCategories()));
559 0 : if( aIt != maAxes.end())
560 0 : nDimension = static_cast< sal_Int32 >( (*aIt).eDimension );
561 : SchXMLTools::CreateCategories(
562 : xDataProvider, mxNewDoc, mrCategoriesAddress,
563 : 0 /* nCooSysIndex */,
564 0 : nDimension, &mrLSequencesPerIndex );
565 : }
566 :
567 0 : uno::Reference< beans::XPropertySet > xDiaProp( mxDiagram, uno::UNO_QUERY );
568 0 : if( xDiaProp.is())
569 : {
570 0 : sal_Bool bIsThreeDim = sal_False;
571 0 : uno::Any aAny = xDiaProp->getPropertyValue( ::rtl::OUString( "Dim3D" ));
572 0 : aAny >>= bIsThreeDim;
573 :
574 : // set 3d scene attributes
575 0 : if( bIsThreeDim )
576 : {
577 : // set scene attributes at diagram
578 0 : maSceneImportHelper.setSceneAttributes( xDiaProp );
579 : }
580 :
581 : // set correct number of lines at series
582 0 : if( ! m_aGlobalSeriesImportInfo.rbAllRangeAddressesAvailable && mnNumOfLinesProp > 0 && maChartTypeServiceName == "com.sun.star.chart2.ColumnChartType" )
583 : {
584 : try
585 : {
586 0 : xDiaProp->setPropertyValue( ::rtl::OUString( "NumberOfLines" ),
587 0 : uno::makeAny( mnNumOfLinesProp ));
588 : }
589 0 : catch( const uno::Exception & rEx )
590 : {
591 : #ifdef DBG_UTIL
592 : rtl::OString aBStr(rtl::OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
593 : OSL_TRACE( "Exception caught for property NumberOfLines: %s", aBStr.getStr());
594 : #else
595 : (void)rEx; // avoid warning for pro build
596 : #endif
597 : }
598 : }
599 :
600 : // #i32366# stock has volume
601 0 : if( ( 0 == mxDiagram->getDiagramType().reverseCompareToAsciiL(
602 0 : RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart.StockDiagram" ))) &&
603 : mbStockHasVolume )
604 : {
605 : try
606 : {
607 0 : xDiaProp->setPropertyValue( ::rtl::OUString( "Volume" ),
608 0 : uno::makeAny( true ));
609 : }
610 0 : catch( const uno::Exception & rEx )
611 : {
612 : #ifdef DBG_UTIL
613 : rtl::OString aBStr(rtl::OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US));
614 : OSL_TRACE("Exception caught for property Volume: %s", aBStr.getStr());
615 : #else
616 : (void)rEx; // avoid warning for pro build
617 : #endif
618 : }
619 0 : }
620 : }
621 :
622 : // set changed size and position after properties (esp. 3d)
623 :
624 0 : uno::Reference< chart::XDiagramPositioning > xDiaPos( mxDiagram, uno::UNO_QUERY );
625 0 : if( xDiaPos.is())
626 : {
627 0 : if( !m_aOuterPositioning.isAutomatic() )
628 : {
629 0 : if( m_aInnerPositioning.hasPosSize() )
630 0 : xDiaPos->setDiagramPositionExcludingAxes( m_aInnerPositioning.getRectangle() );
631 0 : else if( m_aOuterPositioning.hasPosSize() )
632 : {
633 0 : if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan3_3( GetImport().GetModel() ) ) //old version of OOo did write a wrong rectangle for the diagram size
634 0 : xDiaPos->setDiagramPositionIncludingAxesAndAxisTitles( m_aOuterPositioning.getRectangle() );
635 : else
636 0 : xDiaPos->setDiagramPositionIncludingAxes( m_aOuterPositioning.getRectangle() );
637 : }
638 : }
639 : }
640 :
641 0 : SchXMLAxisContext::CorrectAxisPositions( uno::Reference< chart2::XChartDocument >( mrImportHelper.GetChartDocument(), uno::UNO_QUERY ), maChartTypeServiceName, GetImport().GetODFVersion(), m_bAxisPositionAttributeImported );
642 0 : }
643 :
644 : // ========================================
645 :
646 0 : SchXMLDataPointContext::SchXMLDataPointContext( SvXMLImport& rImport, const rtl::OUString& rLocalName,
647 : ::std::list< DataRowPointStyle >& rStyleList,
648 : const ::com::sun::star::uno::Reference<
649 : ::com::sun::star::chart2::XDataSeries >& xSeries,
650 : sal_Int32& rIndex,
651 : bool bSymbolSizeForSeriesIsMissingInFile ) :
652 : SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
653 : mrStyleList( rStyleList ),
654 : m_xSeries( xSeries ),
655 : mrIndex( rIndex ),
656 0 : mbSymbolSizeForSeriesIsMissingInFile( bSymbolSizeForSeriesIsMissingInFile )
657 : {
658 0 : }
659 :
660 0 : SchXMLDataPointContext::~SchXMLDataPointContext()
661 : {
662 0 : }
663 :
664 0 : void SchXMLDataPointContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
665 : {
666 0 : sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
667 0 : ::rtl::OUString sAutoStyleName;
668 0 : sal_Int32 nRepeat = 1;
669 :
670 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
671 : {
672 0 : rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
673 0 : rtl::OUString aLocalName;
674 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
675 :
676 0 : if( nPrefix == XML_NAMESPACE_CHART )
677 : {
678 0 : if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
679 0 : sAutoStyleName = xAttrList->getValueByIndex( i );
680 0 : else if( IsXMLToken( aLocalName, XML_REPEATED ) )
681 0 : nRepeat = xAttrList->getValueByIndex( i ).toInt32();
682 : }
683 0 : }
684 :
685 0 : if( !sAutoStyleName.isEmpty())
686 : {
687 : DataRowPointStyle aStyle(
688 : DataRowPointStyle::DATA_POINT,
689 0 : m_xSeries, mrIndex, nRepeat, sAutoStyleName );
690 0 : aStyle.mbSymbolSizeForSeriesIsMissingInFile = mbSymbolSizeForSeriesIsMissingInFile;
691 0 : mrStyleList.push_back( aStyle );
692 : }
693 0 : mrIndex += nRepeat;
694 0 : }
695 :
696 : // ========================================
697 :
698 0 : SchXMLPositonAttributesHelper::SchXMLPositonAttributesHelper( SvXMLImport& rImporter )
699 : : m_rImport( rImporter )
700 : , m_aPosition(0,0)
701 : , m_aSize(0,0)
702 : , m_bHasSizeWidth( false )
703 : , m_bHasSizeHeight( false )
704 : , m_bHasPositionX( false )
705 : , m_bHasPositionY( false )
706 : , m_bAutoSize( false )
707 0 : , m_bAutoPosition( false )
708 : {
709 0 : }
710 :
711 0 : SchXMLPositonAttributesHelper::~SchXMLPositonAttributesHelper()
712 : {
713 0 : }
714 :
715 0 : bool SchXMLPositonAttributesHelper::hasSize() const
716 : {
717 0 : return m_bHasSizeWidth && m_bHasSizeHeight;
718 : }
719 0 : bool SchXMLPositonAttributesHelper::hasPosition() const
720 : {
721 0 : return m_bHasPositionX && m_bHasPositionY;
722 : }
723 0 : bool SchXMLPositonAttributesHelper::hasPosSize() const
724 : {
725 0 : return hasPosition() && hasSize();
726 : }
727 0 : bool SchXMLPositonAttributesHelper::isAutomatic() const
728 : {
729 0 : return m_bAutoSize || m_bAutoPosition;
730 : }
731 0 : awt::Rectangle SchXMLPositonAttributesHelper::getRectangle() const
732 : {
733 0 : return awt::Rectangle( m_aPosition.X, m_aPosition.Y, m_aSize.Width, m_aSize.Height );
734 : }
735 :
736 0 : bool SchXMLPositonAttributesHelper::readPositioningAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
737 : {
738 : //returns true if the attribute was proccessed
739 0 : bool bReturn = true;
740 :
741 0 : if( XML_NAMESPACE_SVG == nPrefix )
742 : {
743 0 : if( IsXMLToken( rLocalName, XML_X ) )
744 : {
745 0 : m_rImport.GetMM100UnitConverter().convertMeasureToCore(
746 0 : m_aPosition.X, rValue );
747 0 : m_bHasPositionX = true;
748 : }
749 0 : else if( IsXMLToken( rLocalName, XML_Y ) )
750 : {
751 0 : m_rImport.GetMM100UnitConverter().convertMeasureToCore(
752 0 : m_aPosition.Y, rValue );
753 0 : m_bHasPositionY = true;
754 : }
755 0 : else if( IsXMLToken( rLocalName, XML_WIDTH ) )
756 : {
757 0 : m_rImport.GetMM100UnitConverter().convertMeasureToCore(
758 0 : m_aSize.Width, rValue );
759 0 : m_bHasSizeWidth = true;
760 : }
761 0 : else if( IsXMLToken( rLocalName, XML_HEIGHT ) )
762 : {
763 0 : m_rImport.GetMM100UnitConverter().convertMeasureToCore(
764 0 : m_aSize.Height, rValue );
765 0 : m_bHasSizeHeight = true;
766 : }
767 : else
768 0 : bReturn = false;
769 : }
770 : else
771 0 : bReturn = false;
772 :
773 0 : return bReturn;
774 : }
775 :
776 :
777 0 : void SchXMLPositonAttributesHelper::readAutomaticPositioningProperties( XMLPropStyleContext* pPropStyleContext, const SvXMLStylesContext* pStylesCtxt )
778 : {
779 0 : if( pPropStyleContext && pStylesCtxt )
780 : {
781 : //handle automatic position and size
782 : SchXMLTools::getPropertyFromContext(
783 0 : ::rtl::OUString("AutomaticSize"), pPropStyleContext, pStylesCtxt ) >>= m_bAutoSize;
784 : SchXMLTools::getPropertyFromContext(
785 0 : ::rtl::OUString("AutomaticPosition"), pPropStyleContext, pStylesCtxt ) >>= m_bAutoPosition;
786 : }
787 0 : }
788 :
789 : // ========================================
790 :
791 0 : SchXMLCoordinateRegionContext::SchXMLCoordinateRegionContext(
792 : SvXMLImport& rImport
793 : , sal_uInt16 nPrefix
794 : , const rtl::OUString& rLocalName
795 : , SchXMLPositonAttributesHelper& rPositioning )
796 : : SvXMLImportContext( rImport, nPrefix, rLocalName )
797 0 : , m_rPositioning( rPositioning )
798 : {
799 0 : }
800 :
801 0 : SchXMLCoordinateRegionContext::~SchXMLCoordinateRegionContext()
802 : {
803 0 : }
804 :
805 0 : void SchXMLCoordinateRegionContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
806 : {
807 : // parse attributes
808 0 : sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
809 :
810 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
811 : {
812 0 : rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
813 0 : rtl::OUString aLocalName;
814 0 : rtl::OUString aValue = xAttrList->getValueByIndex( i );
815 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
816 0 : m_rPositioning.readPositioningAttribute( nPrefix, aLocalName, aValue );
817 0 : }
818 0 : }
819 :
820 : // ========================================
821 :
822 0 : SchXMLWallFloorContext::SchXMLWallFloorContext(
823 : SchXMLImportHelper& rImpHelper,
824 : SvXMLImport& rImport,
825 : sal_uInt16 nPrefix,
826 : const rtl::OUString& rLocalName,
827 : uno::Reference< chart::XDiagram >& xDiagram,
828 : ContextType eContextType ) :
829 : SvXMLImportContext( rImport, nPrefix, rLocalName ),
830 : mrImportHelper( rImpHelper ),
831 : mxWallFloorSupplier( xDiagram, uno::UNO_QUERY ),
832 0 : meContextType( eContextType )
833 : {
834 0 : }
835 :
836 0 : SchXMLWallFloorContext::~SchXMLWallFloorContext()
837 : {
838 0 : }
839 :
840 0 : void SchXMLWallFloorContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
841 : {
842 0 : if( mxWallFloorSupplier.is())
843 : {
844 0 : sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
845 0 : rtl::OUString sAutoStyleName;
846 :
847 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
848 : {
849 0 : rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
850 0 : rtl::OUString aLocalName;
851 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
852 :
853 0 : if( nPrefix == XML_NAMESPACE_CHART &&
854 0 : IsXMLToken( aLocalName, XML_STYLE_NAME ) )
855 : {
856 0 : sAutoStyleName = xAttrList->getValueByIndex( i );
857 : }
858 0 : }
859 :
860 : // set properties
861 : uno::Reference< beans::XPropertySet > xProp( ( meContextType == CONTEXT_TYPE_WALL )
862 0 : ? mxWallFloorSupplier->getWall()
863 0 : : mxWallFloorSupplier->getFloor(),
864 0 : uno::UNO_QUERY );
865 0 : if( xProp.is())
866 : {
867 0 : if( !sAutoStyleName.isEmpty())
868 : {
869 0 : const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
870 0 : if( pStylesCtxt )
871 : {
872 : const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
873 0 : mrImportHelper.GetChartFamilyID(), sAutoStyleName );
874 :
875 0 : if( pStyle && pStyle->ISA( XMLPropStyleContext ))
876 0 : (( XMLPropStyleContext* )pStyle )->FillPropertySet( xProp );
877 : }
878 : }
879 0 : }
880 : }
881 0 : }
882 :
883 : // ========================================
884 :
885 0 : SchXMLStockContext::SchXMLStockContext(
886 : SchXMLImportHelper& rImpHelper,
887 : SvXMLImport& rImport,
888 : sal_uInt16 nPrefix,
889 : const rtl::OUString& rLocalName,
890 : uno::Reference< chart::XDiagram >& xDiagram,
891 : ContextType eContextType ) :
892 : SvXMLImportContext( rImport, nPrefix, rLocalName ),
893 : mrImportHelper( rImpHelper ),
894 : mxStockPropProvider( xDiagram, uno::UNO_QUERY ),
895 0 : meContextType( eContextType )
896 : {
897 0 : }
898 :
899 0 : SchXMLStockContext::~SchXMLStockContext()
900 : {
901 0 : }
902 :
903 0 : void SchXMLStockContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
904 : {
905 0 : if( mxStockPropProvider.is())
906 : {
907 0 : sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
908 0 : rtl::OUString sAutoStyleName;
909 :
910 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
911 : {
912 0 : rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
913 0 : rtl::OUString aLocalName;
914 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
915 :
916 0 : if( nPrefix == XML_NAMESPACE_CHART &&
917 0 : IsXMLToken( aLocalName, XML_STYLE_NAME ) )
918 : {
919 0 : sAutoStyleName = xAttrList->getValueByIndex( i );
920 : }
921 0 : }
922 :
923 0 : if( !sAutoStyleName.isEmpty())
924 : {
925 : // set properties
926 0 : uno::Reference< beans::XPropertySet > xProp;
927 0 : switch( meContextType )
928 : {
929 : case CONTEXT_TYPE_GAIN:
930 0 : xProp = mxStockPropProvider->getUpBar();
931 0 : break;
932 : case CONTEXT_TYPE_LOSS:
933 0 : xProp = mxStockPropProvider->getDownBar();
934 0 : break;
935 : case CONTEXT_TYPE_RANGE:
936 0 : xProp = mxStockPropProvider->getMinMaxLine();
937 0 : break;
938 : }
939 0 : if( xProp.is())
940 : {
941 0 : const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
942 0 : if( pStylesCtxt )
943 : {
944 : const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
945 0 : mrImportHelper.GetChartFamilyID(), sAutoStyleName );
946 :
947 0 : if( pStyle && pStyle->ISA( XMLPropStyleContext ))
948 0 : (( XMLPropStyleContext* )pStyle )->FillPropertySet( xProp );
949 : }
950 0 : }
951 0 : }
952 : }
953 0 : }
954 :
955 : // ========================================
956 :
957 0 : static void lcl_setErrorBarSequence ( const uno::Reference< chart2::XChartDocument > &xDoc,
958 : const uno::Reference< beans::XPropertySet > &xBarProp,
959 : const rtl::OUString &aRange,
960 : bool bPositiveValue, bool bYError )
961 : {
962 0 : uno::Reference< com::sun::star::chart2::data::XDataProvider > xDataProvider(xDoc->getDataProvider());
963 0 : uno::Reference< com::sun::star::chart2::data::XDataSource > xDataSource( xBarProp, uno::UNO_QUERY );
964 0 : uno::Reference< com::sun::star::chart2::data::XDataSink > xDataSink( xDataSource, uno::UNO_QUERY );
965 :
966 : assert( xDataSink.is() && xDataSource.is() && xDataProvider.is() );
967 :
968 0 : rtl::OUString aXMLRange(lcl_ConvertRange(aRange,xDoc));
969 :
970 : uno::Reference< chart2::data::XDataSequence > xNewSequence(
971 0 : xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
972 :
973 0 : if( xNewSequence.is())
974 : {
975 0 : SchXMLTools::setXMLRangePropertyAtDataSequence(xNewSequence,aXMLRange);
976 :
977 0 : rtl::OUStringBuffer aRoleBuffer("error-bars-");
978 0 : if( bYError )
979 0 : aRoleBuffer.append( sal_Unicode( 'y' ));
980 : else
981 0 : aRoleBuffer.append( sal_Unicode( 'x' ));
982 :
983 0 : rtl::OUString aPlainRole = aRoleBuffer.makeStringAndClear();
984 0 : aRoleBuffer.append( aPlainRole );
985 0 : aRoleBuffer.append( sal_Unicode( '-' ));
986 :
987 0 : if( bPositiveValue )
988 0 : aRoleBuffer = aRoleBuffer.appendAscii( "positive" );
989 : else
990 0 : aRoleBuffer = aRoleBuffer.appendAscii( "negative" );
991 :
992 0 : rtl::OUString aRole = aRoleBuffer.makeStringAndClear();
993 :
994 0 : Reference< beans::XPropertySet > xSeqProp( xNewSequence, uno::UNO_QUERY );
995 :
996 0 : xSeqProp->setPropertyValue("Role", uno::makeAny( aRole ));
997 :
998 0 : Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
999 :
1000 : Reference< chart2::data::XLabeledDataSequence > xLabelSeq(
1001 0 : xFact->createInstance("com.sun.star.chart2.data.LabeledDataSequence"), uno::UNO_QUERY );
1002 :
1003 0 : xLabelSeq->setValues( xNewSequence );
1004 :
1005 : uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
1006 0 : xDataSource->getDataSequences());
1007 :
1008 0 : aSequences.realloc( aSequences.getLength() + 1 );
1009 0 : aSequences[ aSequences.getLength() - 1 ] = xLabelSeq;
1010 0 : xDataSink->setData( aSequences );
1011 0 : }
1012 0 : }
1013 :
1014 0 : SchXMLStatisticsObjectContext::SchXMLStatisticsObjectContext(
1015 :
1016 : SchXMLImportHelper& rImpHelper,
1017 : SvXMLImport& rImport,
1018 : sal_uInt16 nPrefix,
1019 : const rtl::OUString& rLocalName,
1020 : const rtl::OUString &rSeriesStyleName,
1021 : ::std::list< DataRowPointStyle >& rStyleList,
1022 : const ::com::sun::star::uno::Reference<
1023 : ::com::sun::star::chart2::XDataSeries >& xSeries,
1024 : ContextType eContextType,
1025 : const awt::Size & rChartSize ) :
1026 :
1027 : SvXMLImportContext( rImport, nPrefix, rLocalName ),
1028 : mrImportHelper( rImpHelper ),
1029 : mrStyleList( rStyleList ),
1030 : m_xSeries( xSeries ),
1031 : meContextType( eContextType ),
1032 : maChartSize( rChartSize ),
1033 0 : maSeriesStyleName( rSeriesStyleName)
1034 0 : {}
1035 :
1036 0 : SchXMLStatisticsObjectContext::~SchXMLStatisticsObjectContext()
1037 : {
1038 0 : }
1039 :
1040 0 : void SchXMLStatisticsObjectContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
1041 : {
1042 0 : sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
1043 0 : ::rtl::OUString sAutoStyleName;
1044 0 : rtl::OUString aPosRange;
1045 0 : rtl::OUString aNegRange;
1046 0 : bool bYError = true; /// Default errorbar, to be backward compatible with older files!
1047 :
1048 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
1049 : {
1050 0 : rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
1051 0 : rtl::OUString aLocalName;
1052 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
1053 :
1054 0 : if( nPrefix == XML_NAMESPACE_CHART )
1055 : {
1056 0 : if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
1057 0 : sAutoStyleName = xAttrList->getValueByIndex( i );
1058 0 : else if( IsXMLToken( aLocalName, XML_DIMENSION ) )
1059 0 : bYError = xAttrList->getValueByIndex(i) == "y";
1060 0 : else if( IsXMLToken( aLocalName, XML_ERROR_UPPER_RANGE) )
1061 0 : aPosRange = xAttrList->getValueByIndex(i);
1062 0 : else if( IsXMLToken( aLocalName, XML_ERROR_LOWER_RANGE) )
1063 0 : aNegRange = xAttrList->getValueByIndex(i);
1064 : }
1065 0 : }
1066 :
1067 : // note: regression-curves must get a style-object even if there is no
1068 : // auto-style set, because they can contain an equation
1069 0 : if( !sAutoStyleName.isEmpty() || meContextType == CONTEXT_TYPE_REGRESSION_CURVE )
1070 : {
1071 0 : DataRowPointStyle aStyle( DataRowPointStyle::MEAN_VALUE, m_xSeries, -1, 1, sAutoStyleName );
1072 :
1073 0 : switch( meContextType )
1074 : {
1075 : case CONTEXT_TYPE_MEAN_VALUE_LINE:
1076 0 : aStyle.meType = DataRowPointStyle::MEAN_VALUE;
1077 0 : break;
1078 : case CONTEXT_TYPE_REGRESSION_CURVE:
1079 0 : aStyle.meType = DataRowPointStyle::REGRESSION;
1080 0 : break;
1081 : case CONTEXT_TYPE_ERROR_INDICATOR:
1082 : {
1083 0 : aStyle.meType = DataRowPointStyle::ERROR_INDICATOR;
1084 :
1085 : ;
1086 : uno::Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(),
1087 0 : uno::UNO_QUERY );
1088 :
1089 0 : uno::Reference< beans::XPropertySet > xBarProp( xFact->createInstance("com.sun.star.chart2.ErrorBar" ),
1090 0 : uno::UNO_QUERY );
1091 :
1092 0 : xBarProp->setPropertyValue("ErrorBarStyle",uno::makeAny(com::sun::star::chart::ErrorBarStyle::NONE));
1093 0 : xBarProp->setPropertyValue("PositiveError",uno::makeAny(static_cast<double>(0.0)));
1094 0 : xBarProp->setPropertyValue("NegativeError",uno::makeAny(static_cast<double>(0.0)));
1095 0 : xBarProp->setPropertyValue("Weight",uno::makeAny(static_cast<double>(1.0)));
1096 0 : xBarProp->setPropertyValue("ShowPositiveError",uno::makeAny(sal_True));
1097 0 : xBarProp->setPropertyValue("ShowNegativeError",uno::makeAny(sal_True));
1098 :
1099 0 : const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
1100 :
1101 : const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
1102 0 : mrImportHelper.GetChartFamilyID(), sAutoStyleName );
1103 : // note: SvXMLStyleContext::FillPropertySet is not const
1104 : XMLPropStyleContext * pErrorStyleContext =
1105 0 : const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle ));
1106 :
1107 0 : pErrorStyleContext->FillPropertySet( xBarProp );
1108 :
1109 0 : uno::Reference< chart2::XChartDocument > xDoc(GetImport().GetModel(),uno::UNO_QUERY);
1110 :
1111 0 : if (!aPosRange.isEmpty())
1112 0 : lcl_setErrorBarSequence(xDoc,xBarProp,aPosRange,true,bYError);
1113 :
1114 0 : if (!aNegRange.isEmpty())
1115 0 : lcl_setErrorBarSequence(xDoc,xBarProp,aNegRange,false,bYError);
1116 :
1117 0 : if ( !bYError )
1118 : {
1119 0 : aStyle.m_xErrorXProperties.set( xBarProp );
1120 : }
1121 : else
1122 : {
1123 : /// Keep 0DF12 and below support
1124 0 : pStyle = pStylesCtxt->FindStyleChildContext(mrImportHelper.GetChartFamilyID(),
1125 0 : maSeriesStyleName);
1126 :
1127 : XMLPropStyleContext * pSeriesStyleContext =
1128 0 : const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle ));
1129 :
1130 : uno::Any aAny = SchXMLTools::getPropertyFromContext("ErrorBarStyle",
1131 0 : pSeriesStyleContext,pStylesCtxt);
1132 :
1133 0 : if ( aAny.hasValue() )
1134 : {
1135 0 : sal_Int32 aBarStyle = com::sun::star::chart::ErrorBarStyle::NONE;
1136 0 : aAny >>= aBarStyle;
1137 :
1138 : aAny = SchXMLTools::getPropertyFromContext("ShowPositiveError",
1139 0 : pSeriesStyleContext,pStylesCtxt);
1140 :
1141 0 : xBarProp->setPropertyValue("ShowPositiveError",aAny);
1142 :
1143 : aAny = SchXMLTools::getPropertyFromContext("ShowNegativeError",
1144 0 : pSeriesStyleContext,pStylesCtxt);
1145 :
1146 0 : xBarProp->setPropertyValue("ShowNegativeError",aAny);
1147 :
1148 0 : switch(aBarStyle)
1149 : {
1150 : case com::sun::star::chart::ErrorBarStyle::ERROR_MARGIN:
1151 : {
1152 : aAny = SchXMLTools::getPropertyFromContext("NegativeError",
1153 0 : pSeriesStyleContext,pStylesCtxt);
1154 :
1155 0 : xBarProp->setPropertyValue("NegativeError",aAny);
1156 :
1157 : aAny = SchXMLTools::getPropertyFromContext("PositiveError",
1158 0 : pSeriesStyleContext,pStylesCtxt);
1159 :
1160 0 : xBarProp->setPropertyValue("PositiveError",aAny);
1161 : }
1162 0 : break;
1163 : default:
1164 0 : break;
1165 : }
1166 : }
1167 :
1168 0 : aStyle.m_xErrorYProperties.set( xBarProp );
1169 0 : }
1170 : }
1171 0 : break;
1172 : }
1173 :
1174 0 : mrStyleList.push_back( aStyle );
1175 0 : }
1176 0 : }
1177 :
1178 0 : SvXMLImportContext* SchXMLStatisticsObjectContext::CreateChildContext(
1179 : sal_uInt16 nPrefix,
1180 : const rtl::OUString& rLocalName,
1181 : const uno::Reference< xml::sax::XAttributeList >& xAttrList )
1182 : {
1183 0 : SvXMLImportContext* pContext = 0;
1184 :
1185 0 : if( nPrefix == XML_NAMESPACE_CHART &&
1186 0 : IsXMLToken( rLocalName, XML_EQUATION ) )
1187 : {
1188 : pContext = new SchXMLEquationContext(
1189 0 : mrImportHelper, GetImport(), nPrefix, rLocalName, m_xSeries, maChartSize, mrStyleList.back());
1190 : }
1191 : else
1192 : {
1193 0 : pContext = SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
1194 : }
1195 :
1196 0 : return pContext;
1197 : }
1198 :
1199 : // ========================================
1200 :
1201 0 : SchXMLEquationContext::SchXMLEquationContext(
1202 : SchXMLImportHelper& rImpHelper,
1203 : SvXMLImport& rImport,
1204 : sal_uInt16 nPrefix,
1205 : const rtl::OUString& rLocalName,
1206 : const ::com::sun::star::uno::Reference<
1207 : ::com::sun::star::chart2::XDataSeries >& xSeries,
1208 : const awt::Size & rChartSize,
1209 : DataRowPointStyle & rRegressionStyle ) :
1210 : SvXMLImportContext( rImport, nPrefix, rLocalName ),
1211 : mrImportHelper( rImpHelper ),
1212 : mrRegressionStyle( rRegressionStyle ),
1213 : m_xSeries( xSeries ),
1214 0 : maChartSize( rChartSize )
1215 0 : {}
1216 :
1217 0 : SchXMLEquationContext::~SchXMLEquationContext()
1218 0 : {}
1219 :
1220 0 : void SchXMLEquationContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
1221 : {
1222 : // parse attributes
1223 0 : sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
1224 0 : SchXMLImport& rImport = ( SchXMLImport& )GetImport();
1225 0 : const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetRegEquationAttrTokenMap();
1226 0 : OUString sAutoStyleName;
1227 :
1228 0 : bool bShowEquation = true;
1229 0 : bool bShowRSquare = false;
1230 0 : awt::Point aPosition;
1231 0 : bool bHasXPos = false;
1232 0 : bool bHasYPos = false;
1233 :
1234 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
1235 : {
1236 0 : rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
1237 0 : rtl::OUString aLocalName;
1238 0 : rtl::OUString aValue = xAttrList->getValueByIndex( i );
1239 0 : sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
1240 :
1241 0 : switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
1242 : {
1243 : case XML_TOK_REGEQ_POS_X:
1244 0 : rImport.GetMM100UnitConverter().convertMeasureToCore(
1245 0 : aPosition.X, aValue );
1246 0 : bHasXPos = true;
1247 0 : break;
1248 : case XML_TOK_REGEQ_POS_Y:
1249 0 : rImport.GetMM100UnitConverter().convertMeasureToCore(
1250 0 : aPosition.Y, aValue );
1251 0 : bHasYPos = true;
1252 0 : break;
1253 : case XML_TOK_REGEQ_DISPLAY_EQUATION:
1254 0 : ::sax::Converter::convertBool(bShowEquation, aValue);
1255 0 : break;
1256 : case XML_TOK_REGEQ_DISPLAY_R_SQUARE:
1257 0 : ::sax::Converter::convertBool(bShowRSquare, aValue);
1258 0 : break;
1259 : case XML_TOK_REGEQ_STYLE_NAME:
1260 0 : sAutoStyleName = aValue;
1261 0 : break;
1262 : }
1263 0 : }
1264 :
1265 0 : if( !sAutoStyleName.isEmpty() || bShowEquation || bShowRSquare )
1266 : {
1267 0 : uno::Reference< beans::XPropertySet > xEqProp;
1268 0 : uno::Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
1269 0 : if( xFact.is())
1270 0 : xEqProp.set( xFact->createInstance(
1271 0 : ::rtl::OUString( "com.sun.star.chart2.RegressionEquation" )), uno::UNO_QUERY );
1272 0 : if( xEqProp.is())
1273 : {
1274 0 : if( !sAutoStyleName.isEmpty() )
1275 : {
1276 0 : const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
1277 0 : if( pStylesCtxt )
1278 : {
1279 : const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
1280 0 : mrImportHelper.GetChartFamilyID(), sAutoStyleName );
1281 : // note: SvXMLStyleContext::FillPropertySet is not const
1282 : XMLPropStyleContext * pPropStyleContext =
1283 0 : const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle ));
1284 :
1285 0 : if( pPropStyleContext )
1286 0 : pPropStyleContext->FillPropertySet( xEqProp );
1287 : }
1288 : }
1289 0 : xEqProp->setPropertyValue( OUString( "ShowEquation"), uno::makeAny( bShowEquation ));
1290 0 : xEqProp->setPropertyValue( OUString( "ShowCorrelationCoefficient"), uno::makeAny( bShowRSquare ));
1291 :
1292 0 : if( bHasXPos && bHasYPos )
1293 : {
1294 0 : chart2::RelativePosition aRelPos;
1295 0 : aRelPos.Primary = static_cast< double >( aPosition.X ) / static_cast< double >( maChartSize.Width );
1296 0 : aRelPos.Secondary = static_cast< double >( aPosition.Y ) / static_cast< double >( maChartSize.Height );
1297 0 : xEqProp->setPropertyValue( OUString( "RelativePosition" ),
1298 0 : uno::makeAny( aRelPos ));
1299 : }
1300 : OSL_ASSERT( mrRegressionStyle.meType == DataRowPointStyle::REGRESSION );
1301 0 : mrRegressionStyle.m_xEquationProperties.set( xEqProp );
1302 0 : }
1303 0 : }
1304 0 : }
1305 :
1306 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|