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 "SchXMLSeries2Context.hxx"
28 #include "SchXMLPlotAreaContext.hxx"
29 #include "SchXMLSeriesHelper.hxx"
30 #include "SchXMLTools.hxx"
31 #include "PropertyMap.hxx"
32 
33 #include <com/sun/star/chart2/XChartDocument.hpp>
34 #include <com/sun/star/chart2/XDataSeries.hpp>
35 #include <com/sun/star/chart2/XRegressionCurve.hpp>
36 #include <com/sun/star/chart2/data/XDataSink.hpp>
37 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
38 
39 #include <com/sun/star/chart/ChartAxisAssign.hpp>
40 #include <com/sun/star/chart/ChartSymbolType.hpp>
41 #include <com/sun/star/container/XChild.hpp>
42 #include <com/sun/star/chart/ChartLegendPosition.hpp>
43 #include <com/sun/star/drawing/LineStyle.hpp>
44 #include <com/sun/star/embed/Aspects.hpp>
45 #include <com/sun/star/embed/XVisualObject.hpp>
46 #include <com/sun/star/uno/XComponentContext.hpp>
47 
48 // header for define DBG_ERROR1
49 #include <tools/debug.hxx>
50 #include <rtl/ustrbuf.hxx>
51 #include "xmloff/xmlnmspe.hxx"
52 #include <xmloff/xmlimp.hxx>
53 #ifndef _XMLOFF_NMSPMAP_HX
54 #include <xmloff/nmspmap.hxx>
55 #endif
56 #include "SchXMLImport.hxx"
57 // header for class XMLPropStyleContext
58 #include <xmloff/prstylei.hxx>
59 #include <xmloff/xmlprmap.hxx>
60 
61 #include <typeinfo>
62 
63 using namespace ::com::sun::star;
64 using namespace ::xmloff::token;
65 
66 using ::com::sun::star::uno::Reference;
67 using ::com::sun::star::uno::Sequence;
68 using ::rtl::OUString;
69 using ::rtl::OUStringBuffer;
70 
71 // ================================================================================
72 
73 namespace
74 {
75 
76 class SchXMLDomain2Context : public SvXMLImportContext
77 {
78 private:
79 	SchXMLImportHelper& mrImportHelper;
80 	::std::vector< OUString > & mrAddresses;
81 
82 public:
83 	SchXMLDomain2Context( SchXMLImportHelper& rImpHelper,
84                           SvXMLImport& rImport,
85                           sal_uInt16 nPrefix,
86                           const rtl::OUString& rLocalName,
87                           ::std::vector< OUString > & rAddresses );
88 	virtual ~SchXMLDomain2Context();
89 	virtual void StartElement( const Reference< xml::sax::XAttributeList >& xAttrList );
90 };
91 
SchXMLDomain2Context(SchXMLImportHelper & rImpHelper,SvXMLImport & rImport,sal_uInt16 nPrefix,const rtl::OUString & rLocalName,::std::vector<::rtl::OUString> & rAddresses)92 SchXMLDomain2Context::SchXMLDomain2Context(
93 	SchXMLImportHelper& rImpHelper,
94 	SvXMLImport& rImport,
95 	sal_uInt16 nPrefix,
96 	const rtl::OUString& rLocalName,
97 	::std::vector< ::rtl::OUString > & rAddresses ) :
98 		SvXMLImportContext( rImport, nPrefix, rLocalName ),
99 		mrImportHelper( rImpHelper ),
100 		mrAddresses( rAddresses )
101 {
102 }
103 
~SchXMLDomain2Context()104 SchXMLDomain2Context::~SchXMLDomain2Context()
105 {
106 }
107 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)108 void SchXMLDomain2Context::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
109 {
110 	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
111 
112 	for( sal_Int16 i = 0; i < nAttrCount; i++ )
113 	{
114 		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
115 		rtl::OUString aLocalName;
116 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
117 
118 		if( nPrefix == XML_NAMESPACE_TABLE &&
119 			IsXMLToken( aLocalName, XML_CELL_RANGE_ADDRESS ) )
120 		{
121             Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY );
122             mrAddresses.push_back( xAttrList->getValueByIndex( i ));
123 		}
124 	}
125 }
126 
lcl_setAutomaticSymbolSize(const uno::Reference<beans::XPropertySet> & xSeriesOrPointProp,const SvXMLImport & rImport)127 void lcl_setAutomaticSymbolSize( const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp, const SvXMLImport& rImport )
128 {
129     awt::Size aSymbolSize(140,140);//old default for standard sized charts 7cm height
130 
131     double fScale = 1;
132     uno::Reference< chart::XChartDocument > xChartDoc( rImport.GetModel(), uno::UNO_QUERY );
133     if( xChartDoc.is() )
134     {
135         uno::Reference< beans::XPropertySet > xLegendProp( xChartDoc->getLegend(), uno::UNO_QUERY );
136         chart::ChartLegendPosition aLegendPosition = chart::ChartLegendPosition_NONE;
137         if( xLegendProp.is() && (xLegendProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Alignment" ))) >>= aLegendPosition)
138             && chart::ChartLegendPosition_NONE != aLegendPosition )
139         {
140 
141             double fFontHeight = 6.0;
142             if( xLegendProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ))) >>= fFontHeight )
143                 fScale = 0.75*fFontHeight/6.0;
144         }
145         else
146         {
147             uno::Reference< embed::XVisualObject > xVisualObject( rImport.GetModel(), uno::UNO_QUERY );
148             if( xVisualObject.is() )
149             {
150                 awt::Size aPageSize( xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
151                 fScale = aPageSize.Height/7000.0;
152             }
153         }
154         if( fScale>0 )
155         {
156             aSymbolSize.Height = static_cast<sal_Int32>( fScale * aSymbolSize.Height );
157             aSymbolSize.Width = aSymbolSize.Height;
158         }
159     }
160     xSeriesOrPointProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize")),uno::makeAny( aSymbolSize ));
161 }
162 
lcl_setSymbolSizeIfNeeded(const uno::Reference<beans::XPropertySet> & xSeriesOrPointProp,const SvXMLImport & rImport)163 void lcl_setSymbolSizeIfNeeded( const uno::Reference< beans::XPropertySet >& xSeriesOrPointProp, const SvXMLImport& rImport )
164 {
165     if( !xSeriesOrPointProp.is() )
166         return;
167 
168     sal_Int32 nSymbolType = chart::ChartSymbolType::NONE;
169     if( xSeriesOrPointProp.is() && ( xSeriesOrPointProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolType"))) >>= nSymbolType) )
170     {
171         if(chart::ChartSymbolType::NONE!=nSymbolType)
172         {
173             if( chart::ChartSymbolType::BITMAPURL==nSymbolType )
174             {
175                 //set special size for graphics to indicate to use the bitmap size itself
176                 xSeriesOrPointProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize")),uno::makeAny( awt::Size(-1,-1) ));
177             }
178             else
179             {
180                 lcl_setAutomaticSymbolSize( xSeriesOrPointProp, rImport );
181             }
182         }
183     }
184 }
185 
lcl_resetSymbolSizeForPointsIfNecessary(const uno::Reference<beans::XPropertySet> & xPointProp,const SvXMLImport & rImport,const XMLPropStyleContext * pPropStyleContext,const SvXMLStylesContext * pStylesCtxt)186 void lcl_resetSymbolSizeForPointsIfNecessary( const uno::Reference< beans::XPropertySet >& xPointProp, const SvXMLImport& rImport
187     , const XMLPropStyleContext * pPropStyleContext, const SvXMLStylesContext* pStylesCtxt )
188 {
189     uno::Any aASymbolSize( SchXMLTools::getPropertyFromContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize")), pPropStyleContext, pStylesCtxt ) );
190     if( !aASymbolSize.hasValue() )
191         lcl_setSymbolSizeIfNeeded( xPointProp, rImport );
192 }
193 
lcl_insertErrorBarLSequencesToMap(tSchXMLLSequencesPerIndex & rInOutMap,const uno::Reference<beans::XPropertySet> & xSeriesProp,bool bYError=true)194 void lcl_insertErrorBarLSequencesToMap(
195     tSchXMLLSequencesPerIndex & rInOutMap,
196     const uno::Reference< beans::XPropertySet > & xSeriesProp,
197     bool bYError = true )
198 {
199     Reference< chart2::data::XDataSource > xErrorBarSource;
200     const OUString aPropName(
201         bYError
202         ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorBarY" ))
203         : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ErrorBarX" )));
204     if( ( xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBarSource ) &&
205         xErrorBarSource.is() )
206     {
207         Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSequences(
208             xErrorBarSource->getDataSequences());
209         for( sal_Int32 nIndex = 0; nIndex < aLSequences.getLength(); ++nIndex )
210         {
211             // use "0" as data index. This is ok, as it is not used for error bars
212             rInOutMap.insert(
213                 tSchXMLLSequencesPerIndex::value_type(
214                     tSchXMLIndexWithPart( 0, SCH_XML_PART_ERROR_BARS ), aLSequences[ nIndex ] ));
215         }
216     }
217 }
218 
lcl_createAndAddSequenceToSeries(const rtl::OUString & rRole,const rtl::OUString & rRange,const Reference<chart2::XChartDocument> & xChartDoc,const Reference<chart2::XDataSeries> & xSeries)219 Reference< chart2::data::XLabeledDataSequence > lcl_createAndAddSequenceToSeries( const rtl::OUString& rRole
220         , const rtl::OUString& rRange
221         , const Reference< chart2::XChartDocument >& xChartDoc
222         , const Reference< chart2::XDataSeries >& xSeries )
223 {
224     Reference< chart2::data::XLabeledDataSequence > xLabeledSeq;
225 
226     Reference< chart2::data::XDataSource > xSeriesSource( xSeries,uno::UNO_QUERY );
227     Reference< chart2::data::XDataSink > xSeriesSink( xSeries, uno::UNO_QUERY );
228 
229     if( !(rRange.getLength() && xChartDoc.is() && xSeriesSource.is() && xSeriesSink.is()) )
230         return xLabeledSeq;
231 
232     // create a new sequence
233     xLabeledSeq = SchXMLTools::GetNewLabeledDataSequence();
234 
235     // set values at the new sequence
236     Reference< chart2::data::XDataSequence > xSeq = SchXMLTools::CreateDataSequence( rRange, xChartDoc );
237     Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY );
238     if( xSeqProp.is())
239         xSeqProp->setPropertyValue(OUString::createFromAscii("Role"), uno::makeAny( rRole));
240     xLabeledSeq->setValues( xSeq );
241 
242     // add new sequence to data series / push to front to have the correct sequence order if charttype is changed afterwards
243     Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeq( xSeriesSource->getDataSequences());
244     sal_Int32 nOldCount = aOldSeq.getLength();
245     Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeq( nOldCount + 1 );
246     aNewSeq[0]=xLabeledSeq;
247     for( sal_Int32 nN=0; nN<nOldCount; nN++ )
248         aNewSeq[nN+1] = aOldSeq[nN];
249     xSeriesSink->setData( aNewSeq );
250 
251     return xLabeledSeq;
252 }
253 
254 } // anonymous namespace
255 
256 // ================================================================================
257 
SchXMLSeries2Context(SchXMLImportHelper & rImpHelper,SvXMLImport & rImport,const rtl::OUString & rLocalName,const Reference<chart2::XChartDocument> & xNewDoc,std::vector<SchXMLAxis> & rAxes,::std::list<DataRowPointStyle> & rStyleList,sal_Int32 nSeriesIndex,sal_Bool bStockHasVolume,GlobalSeriesImportInfo & rGlobalSeriesImportInfo,const OUString & aGlobalChartTypeName,tSchXMLLSequencesPerIndex & rLSequencesPerIndex,bool & rGlobalChartTypeUsedBySeries,const awt::Size & rChartSize)258 SchXMLSeries2Context::SchXMLSeries2Context(
259 	SchXMLImportHelper& rImpHelper,
260 	SvXMLImport& rImport, const rtl::OUString& rLocalName,
261     const Reference< chart2::XChartDocument > & xNewDoc,
262 	std::vector< SchXMLAxis >& rAxes,
263 	::std::list< DataRowPointStyle >& rStyleList,
264 	sal_Int32 nSeriesIndex,
265 	sal_Bool bStockHasVolume,
266     GlobalSeriesImportInfo& rGlobalSeriesImportInfo,
267     const OUString & aGlobalChartTypeName,
268     tSchXMLLSequencesPerIndex & rLSequencesPerIndex,
269     bool& rGlobalChartTypeUsedBySeries,
270     const awt::Size & rChartSize ) :
271 		SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
272         mrImportHelper( rImpHelper ),
273         mxNewDoc( xNewDoc ),
274 		mrAxes( rAxes ),
275         mrStyleList( rStyleList ),
276 		m_xSeries(0),
277 		mnSeriesIndex( nSeriesIndex ),
278 		mnDataPointIndex( 0 ),
279         m_bStockHasVolume( bStockHasVolume ),
280         m_rGlobalSeriesImportInfo(rGlobalSeriesImportInfo),
281         mpAttachedAxis( NULL ),
282 		maGlobalChartTypeName( aGlobalChartTypeName ),
283         maSeriesChartTypeName( aGlobalChartTypeName ),
284         m_bHasDomainContext(false),
285         mrLSequencesPerIndex( rLSequencesPerIndex ),
286         mrGlobalChartTypeUsedBySeries( rGlobalChartTypeUsedBySeries ),
287         mbSymbolSizeIsMissingInFile(false),
288         maChartSize( rChartSize )
289 {
290     if( 0 == aGlobalChartTypeName.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.DonutChartType" ) ) )
291     {
292         maSeriesChartTypeName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.PieChartType" ));
293         maGlobalChartTypeName = maSeriesChartTypeName;
294     }
295 }
296 
~SchXMLSeries2Context()297 SchXMLSeries2Context::~SchXMLSeries2Context()
298 {
299     OSL_ASSERT( maPostponedSequences.empty());
300 }
301 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)302 void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
303 {
304 	// parse attributes
305 	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
306 	const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetSeriesAttrTokenMap();
307 	mnAttachedAxis = 1;
308 
309     bool bHasRange = false;
310     bool bHasLabelRange = false;
311 
312 	for( sal_Int16 i = 0; i < nAttrCount; i++ )
313 	{
314 		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
315 		rtl::OUString aLocalName;
316 		rtl::OUString aValue = xAttrList->getValueByIndex( i );
317 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
318 
319 		switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
320 		{
321 			case XML_TOK_SERIES_CELL_RANGE:
322                 m_aSeriesRange = aValue;
323                 bHasRange = true;
324 				break;
325 			case XML_TOK_SERIES_LABEL_ADDRESS:
326                 m_aSeriesLabelRange = aValue;
327                 bHasLabelRange = true;
328 				break;
329 			case XML_TOK_SERIES_ATTACHED_AXIS:
330 				{
331 					sal_Int32 nNumOfAxes = mrAxes.size();
332 					for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ )
333 					{
334 						if( aValue.equals( mrAxes[ nCurrent ].aName ) &&
335 							mrAxes[ nCurrent ].eDimension == SCH_XML_AXIS_Y )
336 						{
337 							mpAttachedAxis = &( mrAxes[ nCurrent ] );
338 						}
339 					}
340 				}
341 				break;
342 			case XML_TOK_SERIES_STYLE_NAME:
343 				msAutoStyleName = aValue;
344 				break;
345 			case XML_TOK_SERIES_CHART_CLASS:
346                 {
347                     OUString aClassName;
348 					sal_uInt16 nClassPrefix =
349 						GetImport().GetNamespaceMap().GetKeyByAttrName(
350                             aValue, &aClassName );
351 					if( XML_NAMESPACE_CHART == nClassPrefix )
352                         maSeriesChartTypeName = SchXMLTools::GetChartTypeByClassName( aClassName, false /* bUseOldNames */ );
353 
354                     if( ! maSeriesChartTypeName.getLength())
355                         maSeriesChartTypeName = aClassName;
356                 }
357 				break;
358 		}
359 	}
360 
361     if( mpAttachedAxis )
362 	{
363 		if( mpAttachedAxis->nAxisIndex > 0 )
364 		{
365 			// secondary axis => property has to be set (primary is default)
366 			mnAttachedAxis = 2;
367 		}
368 	}
369 
370     try
371     {
372         OSL_ASSERT( mxNewDoc.is());
373         if( m_rGlobalSeriesImportInfo.rbAllRangeAddressesAvailable && ! bHasRange )
374             m_rGlobalSeriesImportInfo.rbAllRangeAddressesAvailable = sal_False;
375 
376         bool bIsCandleStick = maGlobalChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType"));
377         if( maSeriesChartTypeName.getLength() )
378         {
379             bIsCandleStick = maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.CandleStickChartType"));
380         }
381         else
382         {
383             if( bIsCandleStick
384                 && m_bStockHasVolume
385                 && mnSeriesIndex == 0 )
386             {
387                 maSeriesChartTypeName = OUString::createFromAscii( "com.sun.star.chart2.ColumnChartType" );
388                 bIsCandleStick = false;
389             }
390             else
391             {
392                 maSeriesChartTypeName = maGlobalChartTypeName;
393             }
394         }
395         if( ! mrGlobalChartTypeUsedBySeries )
396             mrGlobalChartTypeUsedBySeries = (maSeriesChartTypeName.equals( maGlobalChartTypeName ));
397         sal_Int32 nCoordinateSystemIndex = 0;//so far we can only import one coordinate system
398         m_xSeries.set(
399             mrImportHelper.GetNewDataSeries( mxNewDoc, nCoordinateSystemIndex, maSeriesChartTypeName, ! mrGlobalChartTypeUsedBySeries ));
400         Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
401             SchXMLTools::GetNewLabeledDataSequence());
402 
403         if( bIsCandleStick )
404         {
405             // set default color for range-line to black (before applying styles)
406             Reference< beans::XPropertySet > xSeriesProp( m_xSeries, uno::UNO_QUERY );
407             if( xSeriesProp.is())
408                 xSeriesProp->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Color")),
409                                                uno::makeAny( sal_Int32( 0x000000 ))); // black
410         }
411         else if( maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.PieChartType")))
412         {
413             //@todo: this property should be saved
414             Reference< beans::XPropertySet > xSeriesProp( m_xSeries, uno::UNO_QUERY );
415             if( xSeriesProp.is())
416                 xSeriesProp->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VaryColorsByPoint")),
417                                                uno::makeAny( true ));
418         }
419 
420         // values
421         Reference< chart2::data::XDataSequence > xSeq;
422         if( bHasRange && m_aSeriesRange.getLength() )
423             xSeq = SchXMLTools::CreateDataSequence( m_aSeriesRange, mxNewDoc );
424 
425         Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY );
426         if( xSeqProp.is())
427         {
428             OUString aMainRole( OUString::createFromAscii("values-y") );
429             if( maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType") ) )
430                 aMainRole = OUString::createFromAscii("values-size");
431             xSeqProp->setPropertyValue(OUString::createFromAscii("Role"), uno::makeAny( aMainRole ));
432         }
433         xLabeledSeq->setValues( xSeq );
434 
435         // register for setting local data if external data provider is not present
436         maPostponedSequences.insert(
437             tSchXMLLSequencesPerIndex::value_type(
438                 tSchXMLIndexWithPart( m_rGlobalSeriesImportInfo.nCurrentDataIndex, SCH_XML_PART_VALUES ), xLabeledSeq ));
439 
440         // label
441         if( bHasLabelRange && m_aSeriesLabelRange.getLength() )
442         {
443             Reference< chart2::data::XDataSequence > xLabelSequence =
444                 SchXMLTools::CreateDataSequence( m_aSeriesLabelRange, mxNewDoc );
445             xLabeledSeq->setLabel( xLabelSequence );
446         }
447 
448         // Note: Even if we have no label, we have to register the label
449         // for creation, because internal data always has labels. If
450         // they don't exist in the original, auto-generated labels are
451         // used for the internal data.
452         maPostponedSequences.insert(
453             tSchXMLLSequencesPerIndex::value_type(
454                 tSchXMLIndexWithPart( m_rGlobalSeriesImportInfo.nCurrentDataIndex, SCH_XML_PART_LABEL ), xLabeledSeq ));
455 
456 
457         Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( &xLabeledSeq, 1 );
458         Reference< chart2::data::XDataSink > xSink( m_xSeries, uno::UNO_QUERY_THROW );
459         xSink->setData( aSeq );
460     }
461     catch( uno::Exception & ex )
462     {
463         (void)ex; // avoid warning for pro build
464         OSL_ENSURE( false, ::rtl::OUStringToOString(
465                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
466                         ::rtl::OUString::createFromAscii( typeid( ex ).name()) +
467                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
468                         ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
469     }
470 
471     //init mbSymbolSizeIsMissingInFile:
472     try
473     {
474         if( msAutoStyleName.getLength() )
475         {
476             const SvXMLStylesContext* pStylesCtxt = mrImportHelper.GetAutoStylesContext();
477 	        if( pStylesCtxt )
478 	        {
479 		        const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
480 			        mrImportHelper.GetChartFamilyID(), msAutoStyleName );
481 
482                 const XMLPropStyleContext* pPropStyleContext = dynamic_cast< const XMLPropStyleContext * >( pStyle );
483 
484                 uno::Any aASymbolSize( SchXMLTools::getPropertyFromContext( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolSize"))
485                     , pPropStyleContext, pStylesCtxt ) );
486                 mbSymbolSizeIsMissingInFile = !aASymbolSize.hasValue();
487 	        }
488         }
489     }
490     catch( uno::Exception & ex )
491     {
492         (void)ex; // avoid warning for pro build
493     }
494 }
495 
496 struct DomainInfo
497 {
DomainInfoDomainInfo498     DomainInfo( const rtl::OUString& rRole, const rtl::OUString& rRange, sal_Int32 nIndex )
499         : aRole(rRole), aRange(rRange), nIndexForLocalData(nIndex)
500     {}
501 
502     rtl::OUString aRole;
503     rtl::OUString aRange;
504     sal_Int32 nIndexForLocalData;
505 };
506 
EndElement()507 void SchXMLSeries2Context::EndElement()
508 {
509     // special handling for different chart types.  This is necessary as the
510     // roles are not yet saved in the file format
511     sal_Int32 nDomainCount = maDomainAddresses.size();
512     bool bIsScatterChart = maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.ScatterChartType"));
513     bool bIsBubbleChart = maSeriesChartTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2.BubbleChartType"));
514     bool bDeleteSeries = false;
515     std::vector< DomainInfo > aDomainInfos;
516 
517     //different handling for different chart types necessary
518     if( bIsScatterChart || ( nDomainCount==1 && !bIsBubbleChart ) )
519     {
520         DomainInfo aDomainInfo( OUString::createFromAscii("values-x"), m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress, m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex ) ;
521         bool bCreateXValues = true;
522         if( !maDomainAddresses.empty() )
523         {
524             if( !m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() )
525             {
526                 m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress = maDomainAddresses.front();
527                 m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
528             }
529             aDomainInfo.aRange = maDomainAddresses.front();
530             aDomainInfo.nIndexForLocalData = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
531             m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
532         }
533         else if( !m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() && !m_bHasDomainContext && mnSeriesIndex==0 )
534         {
535             if( SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( GetImport().GetModel() ) ) //wrong old chart files:
536             {
537                 //for xy charts the first series needs to have a domain
538                 //if this by error iss not the case the first series is taken s x values
539                 //needed for wrong files created while having an addin (e.g. BoxPlot)
540                 m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress = m_aSeriesRange;
541                 m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
542                 bDeleteSeries = true;
543                 bCreateXValues = false;//they will be created for the next series
544             }
545         }
546         if( bCreateXValues )
547             aDomainInfos.push_back( aDomainInfo );
548     }
549     else if( bIsBubbleChart )
550     {
551         if( nDomainCount>1 )
552         {
553             DomainInfo aDomainInfo( OUString::createFromAscii("values-x"), maDomainAddresses[1], m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
554             if( !m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress.getLength() )
555             {
556                 //for bubble chart the second domain contains the x values which should become an index smaller than y values for own data table
557                 //->so second first
558                 m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress = maDomainAddresses[1];
559                 m_rGlobalSeriesImportInfo.nFirstSecondDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
560             }
561             aDomainInfos.push_back( aDomainInfo );
562             m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
563         }
564         else if( m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress.getLength() )
565         {
566             DomainInfo aDomainInfo( OUString::createFromAscii("values-x"), m_rGlobalSeriesImportInfo.aFirstSecondDomainAddress, m_rGlobalSeriesImportInfo.nFirstSecondDomainIndex ) ;
567             aDomainInfos.push_back( aDomainInfo );
568         }
569         if( nDomainCount>0)
570         {
571             DomainInfo aDomainInfo( OUString::createFromAscii("values-y"), maDomainAddresses.front(), m_rGlobalSeriesImportInfo.nCurrentDataIndex ) ;
572             if( !m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() )
573             {
574                 m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress = maDomainAddresses.front();
575                 m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex = m_rGlobalSeriesImportInfo.nCurrentDataIndex;
576             }
577             aDomainInfos.push_back( aDomainInfo );
578             m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
579         }
580         else if( m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress.getLength() )
581         {
582             DomainInfo aDomainInfo( OUString::createFromAscii("values-y"), m_rGlobalSeriesImportInfo.aFirstFirstDomainAddress, m_rGlobalSeriesImportInfo.nFirstFirstDomainIndex ) ;
583             aDomainInfos.push_back( aDomainInfo );
584         }
585     }
586 
587     if( bDeleteSeries )
588     {
589         //delete created series
590         SchXMLImportHelper::DeleteDataSeries(
591             m_xSeries, Reference< chart2::XChartDocument >( GetImport().GetModel(), uno::UNO_QUERY ) );
592     }
593     else
594     {
595         //add style
596 	    if( msAutoStyleName.getLength() ||
597 		    mnAttachedAxis != 1 )
598 	    {
599 		    DataRowPointStyle aStyle(
600                 DataRowPointStyle::DATA_SERIES,
601                 m_xSeries,
602                 -1, 1,
603                 msAutoStyleName, mnAttachedAxis );
604             aStyle.mbSymbolSizeForSeriesIsMissingInFile=mbSymbolSizeIsMissingInFile;
605 		    mrStyleList.push_back( aStyle );
606 	    }
607     }
608 
609     for( std::vector< DomainInfo >::reverse_iterator aIt( aDomainInfos.rbegin() ); aIt!= aDomainInfos.rend(); ++aIt )
610     {
611         DomainInfo aDomainInfo( *aIt );
612         Reference< chart2::data::XLabeledDataSequence > xLabeledSeq =
613             lcl_createAndAddSequenceToSeries( aDomainInfo.aRole, aDomainInfo.aRange, mxNewDoc, m_xSeries );
614         if( xLabeledSeq.is() )
615         {
616             // register for setting local data if external data provider is not present
617             mrLSequencesPerIndex.insert(
618                 tSchXMLLSequencesPerIndex::value_type(
619                     tSchXMLIndexWithPart( aDomainInfo.nIndexForLocalData, SCH_XML_PART_VALUES ), xLabeledSeq ));
620         }
621     }
622 
623     if( !bDeleteSeries )
624     {
625         for( tSchXMLLSequencesPerIndex::const_iterator aIt( maPostponedSequences.begin());
626             aIt != maPostponedSequences.end(); ++aIt )
627         {
628             sal_Int32 nNewIndex = aIt->first.first + nDomainCount;
629             mrLSequencesPerIndex.insert(
630                 tSchXMLLSequencesPerIndex::value_type(
631                     tSchXMLIndexWithPart( nNewIndex, aIt->first.second ), aIt->second ));
632         }
633         m_rGlobalSeriesImportInfo.nCurrentDataIndex++;
634     }
635     maPostponedSequences.clear();
636 }
637 
CreateChildContext(sal_uInt16 nPrefix,const rtl::OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)638 SvXMLImportContext* SchXMLSeries2Context::CreateChildContext(
639 	sal_uInt16 nPrefix,
640 	const rtl::OUString& rLocalName,
641 	const uno::Reference< xml::sax::XAttributeList >&  )
642 {
643 	SvXMLImportContext* pContext = 0;
644 	const SvXMLTokenMap& rTokenMap = mrImportHelper.GetSeriesElemTokenMap();
645 
646 	switch( rTokenMap.Get( nPrefix, rLocalName ))
647 	{
648 		case XML_TOK_SERIES_DOMAIN:
649             if( m_xSeries.is())
650             {
651                 m_bHasDomainContext = true;
652 				pContext = new SchXMLDomain2Context(
653 					mrImportHelper, GetImport(),
654 					nPrefix, rLocalName,
655                     maDomainAddresses );
656 			}
657 			break;
658 
659         case XML_TOK_SERIES_MEAN_VALUE_LINE:
660             pContext = new SchXMLStatisticsObjectContext(
661                 mrImportHelper, GetImport(),
662                 nPrefix, rLocalName,
663                 mrStyleList, m_xSeries,
664                 SchXMLStatisticsObjectContext::CONTEXT_TYPE_MEAN_VALUE_LINE,
665                 maChartSize );
666             break;
667         case XML_TOK_SERIES_REGRESSION_CURVE:
668             pContext = new SchXMLStatisticsObjectContext(
669                 mrImportHelper, GetImport(),
670                 nPrefix, rLocalName,
671                 mrStyleList, m_xSeries,
672                 SchXMLStatisticsObjectContext::CONTEXT_TYPE_REGRESSION_CURVE,
673                 maChartSize );
674             break;
675         case XML_TOK_SERIES_ERROR_INDICATOR:
676             pContext = new SchXMLStatisticsObjectContext(
677                 mrImportHelper, GetImport(),
678                 nPrefix, rLocalName,
679                 mrStyleList, m_xSeries,
680                 SchXMLStatisticsObjectContext::CONTEXT_TYPE_ERROR_INDICATOR,
681                 maChartSize );
682             break;
683 
684 		case XML_TOK_SERIES_DATA_POINT:
685 			pContext = new SchXMLDataPointContext( mrImportHelper, GetImport(), rLocalName,
686 												   mrStyleList, m_xSeries, mnDataPointIndex, mbSymbolSizeIsMissingInFile );
687 			break;
688 
689 		default:
690 			pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
691 	}
692 
693 	return pContext;
694 }
695 
696 //static
initSeriesPropertySets(SeriesDefaultsAndStyles & rSeriesDefaultsAndStyles,const uno::Reference<frame::XModel> & xChartModel)697 void SchXMLSeries2Context::initSeriesPropertySets( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
698         , const uno::Reference< frame::XModel >& xChartModel )
699 {
700     ::std::list< DataRowPointStyle >::iterator iStyle;
701 
702     // iterate over series first and remind propertysets in map
703     // new api <-> old api wrapper
704     ::std::map< Reference< chart2::XDataSeries >, Reference< beans::XPropertySet > > aSeriesMap;
705 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
706 	{
707 		if( iStyle->meType != DataRowPointStyle::DATA_SERIES )
708             continue;
709 
710         if( !iStyle->m_xOldAPISeries.is() )
711             iStyle->m_xOldAPISeries = SchXMLSeriesHelper::createOldAPISeriesPropertySet( iStyle->m_xSeries, xChartModel );
712 
713         aSeriesMap[iStyle->m_xSeries] = iStyle->m_xOldAPISeries;
714 
715     }
716 
717     //initialize m_xOldAPISeries for all other styles also
718     for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
719 	{
720 		if( iStyle->meType == DataRowPointStyle::DATA_SERIES )
721             continue;
722         iStyle->m_xOldAPISeries = aSeriesMap[iStyle->m_xSeries];
723     }
724 }
725 
726 //static
setDefaultsToSeries(SeriesDefaultsAndStyles & rSeriesDefaultsAndStyles)727 void SchXMLSeries2Context::setDefaultsToSeries( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles )
728 {
729     ::std::list< DataRowPointStyle >::iterator iStyle;
730     // iterate over series
731     // call initSeriesPropertySets first
732 
733 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
734 	{
735 		if( iStyle->meType != DataRowPointStyle::DATA_SERIES )
736             continue;
737 
738         try
739         {
740             uno::Reference< beans::XPropertySet > xSeries( iStyle->m_xOldAPISeries );
741             if( !xSeries.is() )
742                 continue;
743 
744             if( rSeriesDefaultsAndStyles.maSymbolTypeDefault.hasValue() )
745                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolType")),rSeriesDefaultsAndStyles.maSymbolTypeDefault);
746             if( rSeriesDefaultsAndStyles.maDataCaptionDefault.hasValue() )
747                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataCaption")),rSeriesDefaultsAndStyles.maDataCaptionDefault);
748 
749             if( rSeriesDefaultsAndStyles.maErrorIndicatorDefault.hasValue() )
750                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorIndicator")),rSeriesDefaultsAndStyles.maErrorIndicatorDefault);
751             if( rSeriesDefaultsAndStyles.maErrorCategoryDefault.hasValue() )
752                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorCategory")),rSeriesDefaultsAndStyles.maErrorCategoryDefault);
753             if( rSeriesDefaultsAndStyles.maConstantErrorLowDefault.hasValue() )
754                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConstantErrorLow")),rSeriesDefaultsAndStyles.maConstantErrorLowDefault);
755             if( rSeriesDefaultsAndStyles.maConstantErrorHighDefault.hasValue() )
756                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConstantErrorHigh")),rSeriesDefaultsAndStyles.maConstantErrorHighDefault);
757             if( rSeriesDefaultsAndStyles.maPercentageErrorDefault.hasValue() )
758                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PercentageError")),rSeriesDefaultsAndStyles.maPercentageErrorDefault);
759             if( rSeriesDefaultsAndStyles.maErrorMarginDefault.hasValue() )
760                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ErrorMargin")),rSeriesDefaultsAndStyles.maErrorMarginDefault);
761 
762             if( rSeriesDefaultsAndStyles.maMeanValueDefault.hasValue() )
763                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MeanValue")),rSeriesDefaultsAndStyles.maMeanValueDefault);
764             if( rSeriesDefaultsAndStyles.maRegressionCurvesDefault.hasValue() )
765                 xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RegressionCurves")),rSeriesDefaultsAndStyles.maRegressionCurvesDefault);
766         }
767         catch( uno::Exception &  )
768         {
769             //end of series reached
770         }
771     }
772 }
773 
774 //static
setStylesToSeries(SeriesDefaultsAndStyles & rSeriesDefaultsAndStyles,const SvXMLStylesContext * pStylesCtxt,const SvXMLStyleContext * & rpStyle,::rtl::OUString & rCurrStyleName,SchXMLImportHelper & rImportHelper,const SvXMLImport & rImport,bool bIsStockChart,tSchXMLLSequencesPerIndex & rInOutLSequencesPerIndex)775 void SchXMLSeries2Context::setStylesToSeries( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
776         , const SvXMLStylesContext* pStylesCtxt
777         , const SvXMLStyleContext*& rpStyle
778         , ::rtl::OUString& rCurrStyleName
779         , SchXMLImportHelper& rImportHelper
780         , const SvXMLImport& rImport
781         , bool bIsStockChart
782         , tSchXMLLSequencesPerIndex & rInOutLSequencesPerIndex )
783 {
784     ::std::list< DataRowPointStyle >::iterator iStyle;
785 
786     // iterate over series
787 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
788 	{
789 		if( iStyle->meType == DataRowPointStyle::DATA_SERIES )
790 		{
791             try
792 			{
793                 uno::Reference< beans::XPropertySet > xSeriesProp( iStyle->m_xOldAPISeries );
794                 if( !xSeriesProp.is() )
795                     continue;
796 
797                 if( iStyle->mnAttachedAxis != 1 )
798 				{
799 					xSeriesProp->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Axis" ))
800                         , uno::makeAny(chart::ChartAxisAssign::SECONDARY_Y) );
801 				}
802 
803 				if( (iStyle->msStyleName).getLength())
804 				{
805 					if( ! rCurrStyleName.equals( iStyle->msStyleName ))
806 					{
807 						rCurrStyleName = iStyle->msStyleName;
808 						rpStyle = pStylesCtxt->FindStyleChildContext(
809 							rImportHelper.GetChartFamilyID(), rCurrStyleName );
810 					}
811 
812                     //set style to series
813                     // note: SvXMLStyleContext::FillPropertySet is not const
814                     XMLPropStyleContext * pPropStyleContext =
815                         const_cast< XMLPropStyleContext * >(
816                             dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
817                     if( pPropStyleContext )
818                     {
819                         // error bar style must be set before the other error
820                         // bar properties (which may be alphabetically before
821                         // this property)
822                         bool bHasErrorBarRangesFromData = false;
823                         {
824                             const ::rtl::OUString aErrorBarStylePropName( RTL_CONSTASCII_USTRINGPARAM("ErrorBarStyle"));
825                             uno::Any aErrorBarStyle(
826                                 SchXMLTools::getPropertyFromContext( aErrorBarStylePropName, pPropStyleContext, pStylesCtxt ));
827                             if( aErrorBarStyle.hasValue())
828                             {
829                                 xSeriesProp->setPropertyValue( aErrorBarStylePropName, aErrorBarStyle );
830                                 sal_Int32 eEBStyle = chart::ErrorBarStyle::NONE;
831                                 bHasErrorBarRangesFromData =
832                                     ( ( aErrorBarStyle >>= eEBStyle ) &&
833                                       eEBStyle == chart::ErrorBarStyle::FROM_DATA );
834                             }
835                         }
836 
837                         //don't set the style to the min max line series of a stock chart
838                         //otherwise the min max line properties gets overwritten and the series becomes invisible typically
839                         bool bIsMinMaxSeries = false;
840                         if( bIsStockChart )
841                         {
842                             if( SchXMLSeriesHelper::isCandleStickSeries( iStyle->m_xSeries
843                                     , uno::Reference< frame::XModel >( rImportHelper.GetChartDocument(), uno::UNO_QUERY ) ) )
844                                 bIsMinMaxSeries = true;
845                         }
846                         if( !bIsMinMaxSeries )
847                         {
848                             pPropStyleContext->FillPropertySet( xSeriesProp );
849                             if( iStyle->mbSymbolSizeForSeriesIsMissingInFile )
850                                 lcl_setSymbolSizeIfNeeded( xSeriesProp, rImport );
851                             if( bHasErrorBarRangesFromData )
852                                 lcl_insertErrorBarLSequencesToMap( rInOutLSequencesPerIndex, xSeriesProp );
853                         }
854                     }
855 				}
856 			}
857 			catch( uno::Exception & rEx )
858 			{
859                 (void)rEx; // avoid warning for pro build
860                 DBG_ERROR1( "Exception caught during setting styles to series: %s",
861                                 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
862 			}
863 		}
864     }
865 }
866 
867 // static
setStylesToStatisticsObjects(SeriesDefaultsAndStyles & rSeriesDefaultsAndStyles,const SvXMLStylesContext * pStylesCtxt,const SvXMLStyleContext * & rpStyle,::rtl::OUString & rCurrStyleName)868 void SchXMLSeries2Context::setStylesToStatisticsObjects( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
869         , const SvXMLStylesContext* pStylesCtxt
870         , const SvXMLStyleContext*& rpStyle
871         , ::rtl::OUString& rCurrStyleName )
872 {
873     ::std::list< DataRowPointStyle >::iterator iStyle;
874 
875     // iterate over regession etc
876 	for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
877     {
878         if( iStyle->meType == DataRowPointStyle::REGRESSION ||
879             iStyle->meType == DataRowPointStyle::ERROR_INDICATOR ||
880             iStyle->meType == DataRowPointStyle::MEAN_VALUE )
881         {
882             try
883             {
884                 uno::Reference< beans::XPropertySet > xSeriesProp( iStyle->m_xOldAPISeries );
885                 if( !xSeriesProp.is() )
886                     continue;
887 
888 				if( (iStyle->msStyleName).getLength())
889 				{
890 					if( ! rCurrStyleName.equals( iStyle->msStyleName ))
891 					{
892 						rCurrStyleName = iStyle->msStyleName;
893 						rpStyle = pStylesCtxt->FindStyleChildContext(
894 							SchXMLImportHelper::GetChartFamilyID(), rCurrStyleName );
895 					}
896 
897                     // note: SvXMLStyleContext::FillPropertySet is not const
898                     XMLPropStyleContext * pPropStyleContext =
899                         const_cast< XMLPropStyleContext * >(
900                             dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
901                     if( pPropStyleContext )
902                     {
903                         Reference< beans::XPropertySet > xStatPropSet;
904                         switch( iStyle->meType )
905                         {
906                             case DataRowPointStyle::MEAN_VALUE:
907                                 xSeriesProp->getPropertyValue(
908                                     OUString( RTL_CONSTASCII_USTRINGPARAM(
909                                                   "DataMeanValueProperties" ))) >>= xStatPropSet;
910                                 break;
911                             case DataRowPointStyle::REGRESSION:
912                                 xSeriesProp->getPropertyValue(
913                                     OUString( RTL_CONSTASCII_USTRINGPARAM(
914                                                   "DataRegressionProperties" ))) >>= xStatPropSet;
915                                 break;
916                             case DataRowPointStyle::ERROR_INDICATOR:
917                                 xSeriesProp->getPropertyValue(
918                                     OUString( RTL_CONSTASCII_USTRINGPARAM(
919                                                   "DataErrorProperties" )))  >>= xStatPropSet;
920                                 break;
921                             default:
922                                 break;
923                         }
924                         if( xStatPropSet.is())
925                             pPropStyleContext->FillPropertySet( xStatPropSet );
926                     }
927                 }
928 
929                 // set equation properties at a regression curve
930                 // note: this must be done after setting the regression
931                 // properties at the old API, otherwise the curve itself does
932                 // not exist here
933                 if( iStyle->meType == DataRowPointStyle::REGRESSION && iStyle->m_xEquationProperties.is())
934                 {
935                     OSL_ASSERT( iStyle->m_xSeries.is());
936                     Reference< chart2::XRegressionCurve > xRegCurve( SchXMLTools::getRegressionCurve( iStyle->m_xSeries ));
937                     if( xRegCurve.is())
938                         xRegCurve->setEquationProperties( iStyle->m_xEquationProperties );
939                 }
940             }
941 			catch( uno::Exception & rEx )
942 			{
943                 (void)rEx; // avoid warning for pro build
944                 DBG_ERROR1( "Exception caught during setting styles to series: %s",
945                                 OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
946 			}
947 		}
948     }
949 }
950 
951 //static
setStylesToDataPoints(SeriesDefaultsAndStyles & rSeriesDefaultsAndStyles,const SvXMLStylesContext * pStylesCtxt,const SvXMLStyleContext * & rpStyle,::rtl::OUString & rCurrStyleName,SchXMLImportHelper & rImportHelper,const SvXMLImport & rImport,bool bIsStockChart,bool bIsDonutChart,bool bSwitchOffLinesForScatter)952 void SchXMLSeries2Context::setStylesToDataPoints( SeriesDefaultsAndStyles& rSeriesDefaultsAndStyles
953         , const SvXMLStylesContext* pStylesCtxt
954         , const SvXMLStyleContext*& rpStyle
955         , ::rtl::OUString& rCurrStyleName
956         , SchXMLImportHelper& rImportHelper
957         , const SvXMLImport& rImport
958         , bool bIsStockChart, bool bIsDonutChart, bool bSwitchOffLinesForScatter )
959 {
960     ::std::list< DataRowPointStyle >::iterator iStyle;
961     for( iStyle = rSeriesDefaultsAndStyles.maSeriesStyleList.begin(); iStyle != rSeriesDefaultsAndStyles.maSeriesStyleList.end(); iStyle++ )
962 	{
963         if( iStyle->meType != DataRowPointStyle::DATA_POINT )
964             continue;
965 
966 		if( iStyle->m_nPointIndex == -1 )
967             continue;
968 
969 		//ignore datapoint properties for stock charts
970         //... todo ...
971         if( bIsStockChart )
972         {
973             if( SchXMLSeriesHelper::isCandleStickSeries( iStyle->m_xSeries, uno::Reference< frame::XModel >( rImportHelper.GetChartDocument(), uno::UNO_QUERY ) ) )
974                 continue;
975         }
976 
977         // data point style
978 		for( sal_Int32 i = 0; i < iStyle->m_nPointRepeat; i++ )
979 		{
980 			try
981 			{
982                 uno::Reference< beans::XPropertySet > xSeriesProp( iStyle->m_xOldAPISeries );
983                 if(!xSeriesProp.is())
984                     continue;
985 
986                 uno::Reference< beans::XPropertySet > xPointProp(
987                     SchXMLSeriesHelper::createOldAPIDataPointPropertySet( iStyle->m_xSeries, iStyle->m_nPointIndex + i
988                         , uno::Reference< frame::XModel >( rImportHelper.GetChartDocument(), uno::UNO_QUERY ) ) );
989 
990                 if( !xPointProp.is() )
991                     continue;
992 
993                 if( bIsDonutChart )
994                 {
995                     //set special series styles for donut charts first
996                     if( !rCurrStyleName.equals( iStyle->msSeriesStyleNameForDonuts ) )
997 					{
998 						rCurrStyleName = iStyle->msSeriesStyleNameForDonuts;
999 						rpStyle = pStylesCtxt->FindStyleChildContext(
1000 							rImportHelper.GetChartFamilyID(), rCurrStyleName );
1001 					}
1002 
1003                     // note: SvXMLStyleContext::FillPropertySet is not const
1004                     XMLPropStyleContext * pPropStyleContext =
1005                         const_cast< XMLPropStyleContext * >(
1006                             dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1007                     if( pPropStyleContext )
1008 						pPropStyleContext->FillPropertySet( xPointProp );
1009                 }
1010 
1011                 try
1012                 {
1013                     //need to set this explicitly here for old files as the new api does not support this property fully anymore
1014                     if( bSwitchOffLinesForScatter )
1015                         xPointProp->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Lines")),uno::makeAny(sal_False));
1016                 }
1017                 catch( uno::Exception & rEx )
1018                 {
1019                     (void)rEx; // avoid warning for pro build
1020                 }
1021 
1022 				if( !rCurrStyleName.equals( iStyle->msStyleName ) )
1023 				{
1024 					rCurrStyleName = iStyle->msStyleName;
1025 					rpStyle = pStylesCtxt->FindStyleChildContext(
1026 						rImportHelper.GetChartFamilyID(), rCurrStyleName );
1027 				}
1028 
1029                 // note: SvXMLStyleContext::FillPropertySet is not const
1030                 XMLPropStyleContext * pPropStyleContext =
1031                     const_cast< XMLPropStyleContext * >(
1032                         dynamic_cast< const XMLPropStyleContext * >( rpStyle ));
1033                 if( pPropStyleContext )
1034                 {
1035                     pPropStyleContext->FillPropertySet( xPointProp );
1036                     if( iStyle->mbSymbolSizeForSeriesIsMissingInFile )
1037                         lcl_resetSymbolSizeForPointsIfNecessary( xPointProp, rImport, pPropStyleContext, pStylesCtxt );
1038                 }
1039 			}
1040 			catch( uno::Exception & rEx )
1041 			{
1042                 (void)rEx; // avoid warning for pro build
1043 				DBG_ERROR1( "Exception caught during setting styles to data points: %s",
1044                                     OUStringToOString( rEx.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
1045 			}
1046 		}
1047 	}	// styles iterator
1048 }
1049 
1050 //static
switchSeriesLinesOff(::std::list<DataRowPointStyle> & rSeriesStyleList)1051 void SchXMLSeries2Context::switchSeriesLinesOff( ::std::list< DataRowPointStyle >& rSeriesStyleList )
1052 {
1053     ::std::list< DataRowPointStyle >::iterator iStyle;
1054     // iterate over series
1055 
1056 	for( iStyle = rSeriesStyleList.begin(); iStyle != rSeriesStyleList.end(); iStyle++ )
1057 	{
1058 		if( iStyle->meType != DataRowPointStyle::DATA_SERIES )
1059             continue;
1060 
1061         try
1062         {
1063             uno::Reference< beans::XPropertySet > xSeries( iStyle->m_xOldAPISeries );
1064             if( !xSeries.is() )
1065                 continue;
1066 
1067             xSeries->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Lines")),uno::makeAny(sal_False));
1068         }
1069         catch( uno::Exception &  )
1070         {
1071             //end of series reached
1072         }
1073     }
1074 }
1075