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_chart2.hxx"
26 #include "PieChartTypeTemplate.hxx"
27 #include "macros.hxx"
28 #include "CommonConverters.hxx"
29 #include "DiagramHelper.hxx"
30 #include "servicenames_charttypes.hxx"
31 #include "DataSeriesHelper.hxx"
32 #include "ContainerHelper.hxx"
33 #include "BaseGFXHelper.hxx"
34 #include "AxisHelper.hxx"
35 #include "ThreeDHelper.hxx"
36 #include "PropertyHelper.hxx"
37 #include <com/sun/star/beans/PropertyAttribute.hpp>
38 #include <com/sun/star/drawing/LineStyle.hpp>
39 #include <com/sun/star/drawing/FillStyle.hpp>
40 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
41 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
42 
43 #include <rtl/math.hxx>
44 
45 #include <algorithm>
46 
47 using namespace ::com::sun::star;
48 
49 using ::rtl::OUString;
50 using ::com::sun::star::beans::Property;
51 using ::com::sun::star::uno::Sequence;
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::uno::Any;
54 using ::osl::MutexGuard;
55 
56 namespace
57 {
58 
59 static const ::rtl::OUString lcl_aServiceName(
60     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.PieChartTypeTemplate" ));
61 
62 enum
63 {
64     PROP_PIE_TEMPLATE_DEFAULT_OFFSET,
65     PROP_PIE_TEMPLATE_OFFSET_MODE,
66     PROP_PIE_TEMPLATE_DIMENSION,
67     PROP_PIE_TEMPLATE_USE_RINGS
68 };
69 
lcl_AddPropertiesToVector(::std::vector<Property> & rOutProperties)70 void lcl_AddPropertiesToVector(
71     ::std::vector< Property > & rOutProperties )
72 {
73     rOutProperties.push_back(
74         Property( C2U( "OffsetMode" ),
75                   PROP_PIE_TEMPLATE_OFFSET_MODE,
76                   ::getCppuType( reinterpret_cast< const chart2::PieChartOffsetMode * >(0)),
77                   beans::PropertyAttribute::BOUND
78                   | beans::PropertyAttribute::MAYBEDEFAULT ));
79     rOutProperties.push_back(
80         Property( C2U( "DefaultOffset" ),
81                   PROP_PIE_TEMPLATE_DEFAULT_OFFSET,
82                   ::getCppuType( reinterpret_cast< const double * >(0)),
83                   beans::PropertyAttribute::BOUND
84                   | beans::PropertyAttribute::MAYBEDEFAULT ));
85     rOutProperties.push_back(
86         Property( C2U( "Dimension" ),
87                   PROP_PIE_TEMPLATE_DIMENSION,
88                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
89                   beans::PropertyAttribute::BOUND
90                   | beans::PropertyAttribute::MAYBEDEFAULT ));
91     rOutProperties.push_back(
92         Property( C2U( "UseRings" ),
93                   PROP_PIE_TEMPLATE_USE_RINGS,
94                   ::getBooleanCppuType(),
95                   beans::PropertyAttribute::BOUND
96                   | beans::PropertyAttribute::MAYBEDEFAULT ));
97 }
98 
99 struct StaticPieChartTypeTemplateDefaults_Initializer
100 {
operator ()__anon6eca3efb0111::StaticPieChartTypeTemplateDefaults_Initializer101     ::chart::tPropertyValueMap* operator()()
102     {
103         static ::chart::tPropertyValueMap aStaticDefaults;
104         lcl_AddDefaultsToMap( aStaticDefaults );
105         return &aStaticDefaults;
106     }
107 private:
lcl_AddDefaultsToMap__anon6eca3efb0111::StaticPieChartTypeTemplateDefaults_Initializer108     void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap )
109     {
110         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_PIE_TEMPLATE_OFFSET_MODE, chart2::PieChartOffsetMode_NONE );
111         ::chart::PropertyHelper::setPropertyValueDefault< double >( rOutMap, PROP_PIE_TEMPLATE_DEFAULT_OFFSET, 0.5 );
112         ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_PIE_TEMPLATE_DIMENSION, 2 );
113         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_PIE_TEMPLATE_USE_RINGS, false );
114     }
115 };
116 
117 struct StaticPieChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticPieChartTypeTemplateDefaults_Initializer >
118 {
119 };
120 
121 struct StaticPieChartTypeTemplateInfoHelper_Initializer
122 {
operator ()__anon6eca3efb0111::StaticPieChartTypeTemplateInfoHelper_Initializer123     ::cppu::OPropertyArrayHelper* operator()()
124     {
125         static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() );
126         return &aPropHelper;
127     }
128 
129 private:
lcl_GetPropertySequence__anon6eca3efb0111::StaticPieChartTypeTemplateInfoHelper_Initializer130     uno::Sequence< Property > lcl_GetPropertySequence()
131     {
132         ::std::vector< ::com::sun::star::beans::Property > aProperties;
133         lcl_AddPropertiesToVector( aProperties );
134 
135         ::std::sort( aProperties.begin(), aProperties.end(),
136                      ::chart::PropertyNameLess() );
137 
138         return ::chart::ContainerHelper::ContainerToSequence( aProperties );
139     }
140 
141 };
142 
143 struct StaticPieChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticPieChartTypeTemplateInfoHelper_Initializer >
144 {
145 };
146 
147 struct StaticPieChartTypeTemplateInfo_Initializer
148 {
operator ()__anon6eca3efb0111::StaticPieChartTypeTemplateInfo_Initializer149     uno::Reference< beans::XPropertySetInfo >* operator()()
150     {
151         static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
152             ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticPieChartTypeTemplateInfoHelper::get() ) );
153         return &xPropertySetInfo;
154     }
155 };
156 
157 struct StaticPieChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticPieChartTypeTemplateInfo_Initializer >
158 {
159 };
160 
161 } // anonymous namespace
162 
163 namespace chart
164 {
165 
PieChartTypeTemplate(uno::Reference<uno::XComponentContext> const & xContext,const::rtl::OUString & rServiceName,chart2::PieChartOffsetMode eMode,bool bRings,sal_Int32 nDim)166 PieChartTypeTemplate::PieChartTypeTemplate(
167     uno::Reference<
168         uno::XComponentContext > const & xContext,
169     const ::rtl::OUString & rServiceName,
170     chart2::PieChartOffsetMode eMode,
171     bool bRings            /* = false */,
172     sal_Int32 nDim         /* = 2 */    ) :
173         ChartTypeTemplate( xContext, rServiceName ),
174         ::property::OPropertySet( m_aMutex )
175 {
176     setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_OFFSET_MODE,    uno::makeAny( eMode ));
177     setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_DIMENSION,      uno::makeAny( nDim ));
178     setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_USE_RINGS,      uno::makeAny( sal_Bool( bRings )));
179 }
180 
~PieChartTypeTemplate()181 PieChartTypeTemplate::~PieChartTypeTemplate()
182 {}
183 
184 // ____ OPropertySet ____
GetDefaultValue(sal_Int32 nHandle) const185 uno::Any PieChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const
186     throw(beans::UnknownPropertyException)
187 {
188     const tPropertyValueMap& rStaticDefaults = *StaticPieChartTypeTemplateDefaults::get();
189     tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
190     if( aFound == rStaticDefaults.end() )
191         return uno::Any();
192     return (*aFound).second;
193 }
194 
getInfoHelper()195 ::cppu::IPropertyArrayHelper & SAL_CALL PieChartTypeTemplate::getInfoHelper()
196 {
197     return *StaticPieChartTypeTemplateInfoHelper::get();
198 }
199 
200 // ____ XPropertySet ____
getPropertySetInfo()201 uno::Reference< beans::XPropertySetInfo > SAL_CALL PieChartTypeTemplate::getPropertySetInfo()
202     throw (uno::RuntimeException)
203 {
204     return *StaticPieChartTypeTemplateInfo::get();
205 }
206 
207 // ____ ChartTypeTemplate ____
getDimension() const208 sal_Int32 PieChartTypeTemplate::getDimension() const
209 {
210     sal_Int32 nDim = 2;
211     try
212     {
213         // note: UNO-methods are never const
214         const_cast< PieChartTypeTemplate * >( this )->
215             getFastPropertyValue( PROP_PIE_TEMPLATE_DIMENSION ) >>= nDim;
216     }
217     catch( beans::UnknownPropertyException & ex )
218     {
219         ASSERT_EXCEPTION( ex );
220     }
221 
222     return nDim;
223 }
224 
getAxisCountByDimension(sal_Int32)225 sal_Int32 PieChartTypeTemplate::getAxisCountByDimension( sal_Int32 /*nDimension*/ )
226 {
227     return 0;
228 }
229 
230 // void PieChartTypeTemplate::createAxes(
231 //     const Sequence< Reference< chart2::XCoordinateSystem > > & rCoordSys )
232 // {
233 // }
234 
adaptAxes(const uno::Sequence<uno::Reference<chart2::XCoordinateSystem>> &)235 void PieChartTypeTemplate::adaptAxes(
236     const uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > & /*rCoordSys*/ )
237 {
238     // hide existing axes
239     //hhhh todo
240 }
241 
adaptScales(const Sequence<Reference<chart2::XCoordinateSystem>> & aCooSysSeq,const Reference<chart2::data::XLabeledDataSequence> & xCategories)242 void PieChartTypeTemplate::adaptScales(
243     const Sequence< Reference< chart2::XCoordinateSystem > > & aCooSysSeq,
244     const Reference< chart2::data::XLabeledDataSequence > & xCategories //@todo: in future there may be more than one sequence of categories (e.g. charttype with categories at x and y axis )
245     )
246 {
247     ChartTypeTemplate::adaptScales( aCooSysSeq, xCategories );
248 
249     //remove explicit scalings from radius axis
250     //and ensure correct orientation of scales for donuts
251 
252     for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
253     {
254         try
255         {
256             Reference< chart2::XAxis > xAxis( AxisHelper::getAxis( 1 /*nDimensionIndex*/,0 /*nAxisIndex*/
257                     , aCooSysSeq[nCooSysIdx] ) );
258             if( xAxis.is() )
259             {
260                 chart2::ScaleData aScaleData( xAxis->getScaleData() );
261                 AxisHelper::removeExplicitScaling( aScaleData );
262                 aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
263                 xAxis->setScaleData( aScaleData );
264             }
265 
266             //------
267 
268             xAxis = AxisHelper::getAxis( 0 /*nDimensionIndex*/,0 /*nAxisIndex*/
269                     , aCooSysSeq[nCooSysIdx] );
270             if( xAxis.is() )
271             {
272                 chart2::ScaleData aScaleData( xAxis->getScaleData() );
273                 aScaleData.Orientation = chart2::AxisOrientation_REVERSE;
274                 xAxis->setScaleData( aScaleData );
275             }
276         }
277         catch( const uno::Exception & ex )
278         {
279             ASSERT_EXCEPTION( ex );
280         }
281     }
282 }
283 
createChartTypes(const Sequence<Sequence<Reference<chart2::XDataSeries>>> & aSeriesSeq,const Sequence<Reference<chart2::XCoordinateSystem>> & rCoordSys,const Sequence<Reference<chart2::XChartType>> &)284 void PieChartTypeTemplate::createChartTypes(
285     const Sequence< Sequence< Reference< chart2::XDataSeries > > > & aSeriesSeq,
286     const Sequence< Reference< chart2::XCoordinateSystem > > & rCoordSys,
287     const Sequence< Reference< chart2::XChartType > >& /* aOldChartTypesSeq */ )
288 {
289     if( rCoordSys.getLength() == 0 ||
290         ! rCoordSys[0].is() )
291         return;
292 
293     try
294     {
295         Reference< lang::XMultiServiceFactory > xFact(
296             GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
297 
298         Reference< chart2::XChartType > xCT(
299             xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_PIE ), uno::UNO_QUERY_THROW );
300         Reference< beans::XPropertySet > xCTProp( xCT, uno::UNO_QUERY );
301         if( xCTProp.is())
302         {
303             xCTProp->setPropertyValue(
304                 C2U( "UseRings" ), getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ));
305         }
306         Reference< chart2::XChartTypeContainer > xCTCnt( rCoordSys[0], uno::UNO_QUERY_THROW );
307         xCTCnt->setChartTypes( Sequence< Reference< chart2::XChartType > >( &xCT, 1 ));
308 
309         if( aSeriesSeq.getLength() > 0 )
310         {
311             Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW );
312             Sequence< Reference< chart2::XDataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq ));
313             xDSCnt->setDataSeries( aFlatSeriesSeq );
314 
315             DataSeriesHelper::setStackModeAtSeries(
316                 aFlatSeriesSeq, rCoordSys[0], getStackMode( 0 ));
317         }
318     }
319     catch( uno::Exception & ex )
320     {
321         ASSERT_EXCEPTION( ex );
322     }
323 }
324 
325 // ____ XChartTypeTemplate ____
matchesTemplate(const uno::Reference<chart2::XDiagram> & xDiagram,sal_Bool bAdaptProperties)326 sal_Bool SAL_CALL PieChartTypeTemplate::matchesTemplate(
327     const uno::Reference< chart2::XDiagram >& xDiagram,
328     sal_Bool bAdaptProperties )
329     throw (uno::RuntimeException)
330 {
331     sal_Bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties );
332 
333     sal_Bool bTemplateUsesRings = sal_False;
334     getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ) >>= bTemplateUsesRings;
335     chart2::PieChartOffsetMode ePieOffsetMode;
336     getFastPropertyValue( PROP_PIE_TEMPLATE_OFFSET_MODE ) >>= ePieOffsetMode;
337 
338     //check offset-mode
339     if( bResult )
340     {
341         try
342         {
343             double fOffset=0.0;
344             bool bAllOffsetsEqual = true;
345 
346             ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
347                 DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
348 
349             //check offset of outer series
350             if( aSeriesVec.size() )
351             {
352                 sal_Int32 nOuterSeriesIndex = 0; //@todo in future this will depend on Orientation of the radius axis scale
353                 Reference< chart2::XDataSeries > xSeries( aSeriesVec[nOuterSeriesIndex] );
354                 Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW );
355                 xProp->getPropertyValue( C2U( "Offset" )) >>= fOffset;
356 
357                 //get AttributedDataPoints
358                 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
359                 if( xProp->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
360                 {
361                     for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
362                     {
363                         uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
364                         if(xPointProp.is())
365                         {
366                             double fPointOffset=0.0;
367                             if( (xProp->getPropertyValue( C2U( "Offset" )) >>= fPointOffset ) )
368                             {
369                                 if( ! ::rtl::math::approxEqual( fPointOffset, fOffset ) )
370                                 {
371                                     bAllOffsetsEqual = false;
372                                     break;
373                                 }
374                             }
375                         }
376                     }
377                 }
378             }
379 
380             chart2::PieChartOffsetMode eOffsetMode = chart2::PieChartOffsetMode_NONE;
381             if( bAllOffsetsEqual && fOffset > 0.0 )
382             {
383                 eOffsetMode = chart2::PieChartOffsetMode_ALL_EXPLODED;
384                 if( bAdaptProperties )
385                     setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_DEFAULT_OFFSET, uno::makeAny( fOffset ));
386             }
387 
388             bResult = ( eOffsetMode == ePieOffsetMode );
389         }
390         catch( uno::Exception & ex )
391         {
392             ASSERT_EXCEPTION( ex );
393             bResult = false;
394         }
395     }
396 
397     //check UseRings
398     if( bResult )
399     {
400         uno::Reference< beans::XPropertySet > xCTProp(
401             DiagramHelper::getChartTypeByIndex( xDiagram, 0 ), uno::UNO_QUERY_THROW );
402         sal_Bool bUseRings = false;
403         if( xCTProp->getPropertyValue( C2U( "UseRings" )) >>= bUseRings )
404         {
405             bResult = ( bTemplateUsesRings == bUseRings );
406         }
407     }
408 
409     return bResult;
410 }
411 
getChartTypeForIndex(sal_Int32)412 Reference< chart2::XChartType > PieChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ )
413 {
414     Reference< chart2::XChartType > xResult;
415 
416     try
417     {
418         Reference< lang::XMultiServiceFactory > xFact(
419             GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
420         xResult.set( xFact->createInstance(
421                          CHART2_SERVICE_NAME_CHARTTYPE_PIE ), uno::UNO_QUERY_THROW );
422         Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY );
423         if( xCTProp.is())
424         {
425             xCTProp->setPropertyValue(
426                 C2U( "UseRings" ), getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ));
427         }
428 
429     }
430     catch( uno::Exception & ex )
431     {
432         ASSERT_EXCEPTION( ex );
433     }
434 
435     return xResult;
436 }
437 
getChartTypeForNewSeries(const uno::Sequence<Reference<chart2::XChartType>> & aFormerlyUsedChartTypes)438 Reference< chart2::XChartType > SAL_CALL PieChartTypeTemplate::getChartTypeForNewSeries(
439         const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes )
440     throw (uno::RuntimeException)
441 {
442     Reference< chart2::XChartType > xResult;
443 
444     try
445     {
446         Reference< lang::XMultiServiceFactory > xFact(
447             GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
448         xResult.set( xFact->createInstance(
449                          CHART2_SERVICE_NAME_CHARTTYPE_PIE ), uno::UNO_QUERY_THROW );
450         ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem( aFormerlyUsedChartTypes, xResult );
451         Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY );
452         if( xCTProp.is())
453         {
454             xCTProp->setPropertyValue(
455                 C2U( "UseRings" ), getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ));
456         }
457 
458     }
459     catch( uno::Exception & ex )
460     {
461         ASSERT_EXCEPTION( ex );
462     }
463 
464     return xResult;
465 }
466 
applyStyle(const Reference<chart2::XDataSeries> & xSeries,::sal_Int32 nChartTypeIndex,::sal_Int32 nSeriesIndex,::sal_Int32 nSeriesCount)467 void SAL_CALL PieChartTypeTemplate::applyStyle(
468     const Reference< chart2::XDataSeries >& xSeries,
469     ::sal_Int32 nChartTypeIndex,
470     ::sal_Int32 nSeriesIndex,
471     ::sal_Int32 nSeriesCount )
472     throw (uno::RuntimeException)
473 {
474     ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount );
475 
476     try
477     {
478         uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW );
479 
480         sal_Bool bTemplateUsesRings = sal_False;
481         getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ) >>= bTemplateUsesRings;
482         sal_Int32 nOuterSeriesIndex = 0; //@todo in future this will depend on Orientation of the radius axis scale
483         if( nSeriesIndex == nOuterSeriesIndex )
484         {
485             const OUString aOffsetPropName( RTL_CONSTASCII_USTRINGPARAM("Offset"));
486             // get offset mode
487             chart2::PieChartOffsetMode ePieOffsetMode;
488             this->getFastPropertyValue( PROP_PIE_TEMPLATE_OFFSET_MODE ) >>= ePieOffsetMode;
489 
490             // get default offset
491             double fDefaultOffset = 0.5;
492             this->getFastPropertyValue( PROP_PIE_TEMPLATE_DEFAULT_OFFSET ) >>= fDefaultOffset;
493             double fOffsetToSet = fDefaultOffset;
494 
495             uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
496             xProp->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList;
497 
498             // determine whether to set the new offset
499             bool bSetOffset = ( ePieOffsetMode == chart2::PieChartOffsetMode_ALL_EXPLODED );
500             if( !bSetOffset &&
501                 (ePieOffsetMode == chart2::PieChartOffsetMode_NONE) )
502             {
503                 // set offset to 0 if the offset was exactly "all exploded"
504                 // before (individual offsets are kept)
505                 double fOffset = 0.0;
506                 if( (xProp->getPropertyValue( aOffsetPropName ) >>= fOffset) &&
507                     ::rtl::math::approxEqual( fOffset, fDefaultOffset ))
508                 {
509                     fOffsetToSet = 0.0;
510                     bSetOffset = true;
511                     for( sal_Int32 nPtIdx=0; nPtIdx<aAttributedDataPointIndexList.getLength(); ++nPtIdx )
512                     {
513                         uno::Reference< beans::XPropertySet > xPointProp(
514                             xSeries->getDataPointByIndex( aAttributedDataPointIndexList[ nPtIdx ] ));
515                         uno::Reference< beans::XPropertyState > xPointState( xPointProp, uno::UNO_QUERY );
516                         double fPointOffset = 0.0;
517                         if( xPointState.is() &&
518                             (xPointState->getPropertyState( aOffsetPropName ) == beans::PropertyState_DIRECT_VALUE) &&
519                             xPointProp.is() &&
520                             (xPointProp->getPropertyValue( aOffsetPropName ) >>= fPointOffset ) &&
521                             ! ::rtl::math::approxEqual( fPointOffset, fDefaultOffset ) )
522                         {
523                             bSetOffset = false;
524                             break;
525                         }
526                     }
527                 }
528             }
529 
530             if( bSetOffset )
531             {
532                 // set the offset to the series and to the attributed data points
533                 xProp->setPropertyValue( aOffsetPropName, uno::makeAny( fOffsetToSet ));
534 
535                 // remove hard attributes from data points
536                 for( sal_Int32 nPtIdx=0; nPtIdx<aAttributedDataPointIndexList.getLength(); ++nPtIdx )
537                 {
538                     uno::Reference< beans::XPropertyState > xPointState(
539                         xSeries->getDataPointByIndex( aAttributedDataPointIndexList[ nPtIdx ] ), uno::UNO_QUERY );
540                     if( xPointState.is())
541                         xPointState->setPropertyToDefault( aOffsetPropName );
542                 }
543             }
544         }
545 
546         // line style
547         DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
548 
549         // vary colors by point
550         xProp->setPropertyValue( C2U("VaryColorsByPoint"), uno::makeAny( true ));
551     }
552     catch( uno::Exception & ex )
553     {
554         ASSERT_EXCEPTION( ex );
555     }
556 }
557 
558 
resetStyles(const Reference<chart2::XDiagram> & xDiagram)559 void SAL_CALL PieChartTypeTemplate::resetStyles( const Reference< chart2::XDiagram >& xDiagram )
560     throw (uno::RuntimeException)
561 {
562     // reset axes and grids
563     Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
564     if( xCooSysCnt.is())
565     {
566         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
567         ChartTypeTemplate::createAxes( aCooSysSeq );
568 
569         //reset scale orientation
570         for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
571         {
572             try
573             {
574                 Reference< chart2::XAxis > xAxis( AxisHelper::getAxis( 0 /*nDimensionIndex*/,0 /*nAxisIndex*/
575                         , aCooSysSeq[nCooSysIdx] ) );
576                 if( xAxis.is() )
577                 {
578                     chart2::ScaleData aScaleData( xAxis->getScaleData() );
579                     aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
580                     xAxis->setScaleData( aScaleData );
581                 }
582 
583                 xAxis = AxisHelper::getAxis( 1, 0, aCooSysSeq[nCooSysIdx] );
584                 if( xAxis.is() )
585                 {
586                     chart2::ScaleData aScaleData( xAxis->getScaleData() );
587                     aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
588                     xAxis->setScaleData( aScaleData );
589                 }
590             }
591             catch( const uno::Exception & ex )
592             {
593                 ASSERT_EXCEPTION( ex );
594             }
595         }
596     }
597 
598     ChartTypeTemplate::resetStyles( xDiagram );
599 
600     // vary colors by point,
601     // line style
602     ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
603         DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
604     uno::Any aLineStyleAny( uno::makeAny( drawing::LineStyle_NONE ));
605     for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeriesVec.begin());
606          aIt != aSeriesVec.end(); ++aIt )
607     {
608         Reference< beans::XPropertyState > xState( *aIt, uno::UNO_QUERY );
609         if( xState.is())
610         {
611             xState->setPropertyToDefault( C2U("VaryColorsByPoint"));
612             Reference< beans::XPropertySet > xProp( xState, uno::UNO_QUERY );
613             if( xProp.is() &&
614                 xProp->getPropertyValue( C2U("BorderStyle")) == aLineStyleAny )
615             {
616                 xState->setPropertyToDefault( C2U("BorderStyle"));
617             }
618         }
619     }
620 
621     //reset scene properties
622     ThreeDHelper::setDefaultRotation( uno::Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY ), false );
623 }
624 
625 // ____ XChartTypeTemplate ____
adaptDiagram(const uno::Reference<chart2::XDiagram> & xDiagram)626 void PieChartTypeTemplate::adaptDiagram( const uno::Reference< chart2::XDiagram >& xDiagram )
627 {
628     if( !xDiagram.is() )
629         return;
630 
631     //different default for scene geometry:
632     ThreeDHelper::setDefaultRotation( uno::Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY ), true );
633 }
634 
635 // ----------------------------------------
636 
getSupportedServiceNames_Static()637 uno::Sequence< ::rtl::OUString > PieChartTypeTemplate::getSupportedServiceNames_Static()
638 {
639     uno::Sequence< ::rtl::OUString > aServices( 2 );
640     aServices[ 0 ] = lcl_aServiceName;
641     aServices[ 1 ] = C2U( "com.sun.star.chart2.ChartTypeTemplate" );
642     return aServices;
643 }
644 
645 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
646 APPHELPER_XSERVICEINFO_IMPL( PieChartTypeTemplate, lcl_aServiceName );
647 
648 IMPLEMENT_FORWARD_XINTERFACE2( PieChartTypeTemplate, ChartTypeTemplate, OPropertySet )
649 IMPLEMENT_FORWARD_XTYPEPROVIDER2( PieChartTypeTemplate, ChartTypeTemplate, OPropertySet )
650 
651 } //  namespace chart
652