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