xref: /trunk/main/xmloff/source/chart/SchXMLPlotAreaContext.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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