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