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 "ScatterChartTypeTemplate.hxx"
27 #include "macros.hxx"
28 #include "XYDataInterpreter.hxx"
29 #include "CartesianCoordinateSystem.hxx"
30 #include "DiagramHelper.hxx"
31 #include "servicenames_charttypes.hxx"
32 #include "ContainerHelper.hxx"
33 #include "DataSeriesHelper.hxx"
34 #include <com/sun/star/chart2/SymbolStyle.hpp>
35 #include <com/sun/star/chart2/Symbol.hpp>
36 #include <com/sun/star/drawing/LineStyle.hpp>
37 #include "PropertyHelper.hxx"
38 #include <com/sun/star/beans/PropertyAttribute.hpp>
39 
40 #include <algorithm>
41 
42 using namespace ::com::sun::star;
43 
44 using ::com::sun::star::uno::Reference;
45 using ::com::sun::star::uno::Sequence;
46 using ::rtl::OUString;
47 using ::com::sun::star::beans::Property;
48 using ::com::sun::star::uno::Reference;
49 using ::com::sun::star::uno::Any;
50 using ::osl::MutexGuard;
51 
52 namespace
53 {
54 
55 static const OUString lcl_aServiceName(
56     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.ScatterChartTypeTemplate" ));
57 
58 enum
59 {
60     PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE,
61     PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION,
62     PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER
63 
64 };
65 
lcl_AddPropertiesToVector(::std::vector<Property> & rOutProperties)66 void lcl_AddPropertiesToVector(
67     ::std::vector< Property > & rOutProperties )
68 {
69     rOutProperties.push_back(
70         Property( C2U( "CurveStyle" ),
71                   PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE,
72                   ::getCppuType( reinterpret_cast< const chart2::CurveStyle * >(0)),
73                   beans::PropertyAttribute::BOUND
74                   | beans::PropertyAttribute::MAYBEDEFAULT ));
75     rOutProperties.push_back(
76         Property( C2U( "CurveResolution" ),
77                   PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION,
78                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
79                   beans::PropertyAttribute::BOUND
80                   | beans::PropertyAttribute::MAYBEDEFAULT ));
81     rOutProperties.push_back(
82         Property( C2U( "SplineOrder" ),
83                   PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER,
84                   ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)),
85                   beans::PropertyAttribute::BOUND
86                   | beans::PropertyAttribute::MAYBEDEFAULT ));
87 }
88 
89 struct StaticScatterChartTypeTemplateDefaults_Initializer
90 {
operator ()__anon5213193b0111::StaticScatterChartTypeTemplateDefaults_Initializer91     ::chart::tPropertyValueMap* operator()()
92     {
93         static ::chart::tPropertyValueMap aStaticDefaults;
94         lcl_AddDefaultsToMap( aStaticDefaults );
95         return &aStaticDefaults;
96     }
97 private:
lcl_AddDefaultsToMap__anon5213193b0111::StaticScatterChartTypeTemplateDefaults_Initializer98     void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap )
99     {
100         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, chart2::CurveStyle_LINES );
101         ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION, 20 );
102 
103         // todo: check whether order 3 means polygons of order 3 or 2. (see
104         // http://www.people.nnov.ru/fractal/Splines/Basis.htm )
105         ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER, 3 );
106     }
107 };
108 
109 struct StaticScatterChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticScatterChartTypeTemplateDefaults_Initializer >
110 {
111 };
112 
113 struct StaticScatterChartTypeTemplateInfoHelper_Initializer
114 {
operator ()__anon5213193b0111::StaticScatterChartTypeTemplateInfoHelper_Initializer115     ::cppu::OPropertyArrayHelper* operator()()
116     {
117         static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() );
118         return &aPropHelper;
119     }
120 
121 private:
lcl_GetPropertySequence__anon5213193b0111::StaticScatterChartTypeTemplateInfoHelper_Initializer122     Sequence< Property > lcl_GetPropertySequence()
123     {
124         ::std::vector< ::com::sun::star::beans::Property > aProperties;
125         lcl_AddPropertiesToVector( aProperties );
126 
127         ::std::sort( aProperties.begin(), aProperties.end(),
128                      ::chart::PropertyNameLess() );
129 
130         return ::chart::ContainerHelper::ContainerToSequence( aProperties );
131     }
132 
133 };
134 
135 struct StaticScatterChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticScatterChartTypeTemplateInfoHelper_Initializer >
136 {
137 };
138 
139 struct StaticScatterChartTypeTemplateInfo_Initializer
140 {
operator ()__anon5213193b0111::StaticScatterChartTypeTemplateInfo_Initializer141     uno::Reference< beans::XPropertySetInfo >* operator()()
142     {
143         static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
144             ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticScatterChartTypeTemplateInfoHelper::get() ) );
145         return &xPropertySetInfo;
146     }
147 };
148 
149 struct StaticScatterChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticScatterChartTypeTemplateInfo_Initializer >
150 {
151 };
152 
153 } // anonymous namespace
154 
155 namespace chart
156 {
157 
ScatterChartTypeTemplate(Reference<uno::XComponentContext> const & xContext,const OUString & rServiceName,bool bSymbols,bool bHasLines,sal_Int32 nDim)158 ScatterChartTypeTemplate::ScatterChartTypeTemplate(
159     Reference<
160         uno::XComponentContext > const & xContext,
161     const OUString & rServiceName,
162     bool bSymbols,
163     bool bHasLines /* = true */,
164     sal_Int32 nDim /* = 2 */ ) :
165         ChartTypeTemplate( xContext, rServiceName ),
166         ::property::OPropertySet( m_aMutex ),
167     m_bHasSymbols( bSymbols ),
168     m_bHasLines( bHasLines ),
169     m_nDim( nDim )
170 {
171     if( nDim == 3 )
172         m_bHasSymbols = false;
173 }
174 
~ScatterChartTypeTemplate()175 ScatterChartTypeTemplate::~ScatterChartTypeTemplate()
176 {}
177 
178 // ____ OPropertySet ____
GetDefaultValue(sal_Int32 nHandle) const179 uno::Any ScatterChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const
180     throw(beans::UnknownPropertyException)
181 {
182     const tPropertyValueMap& rStaticDefaults = *StaticScatterChartTypeTemplateDefaults::get();
183     tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
184     if( aFound == rStaticDefaults.end() )
185         return uno::Any();
186     return (*aFound).second;
187 }
188 
getInfoHelper()189 ::cppu::IPropertyArrayHelper & SAL_CALL ScatterChartTypeTemplate::getInfoHelper()
190 {
191     return *StaticScatterChartTypeTemplateInfoHelper::get();
192 }
193 
194 // ____ XPropertySet ____
getPropertySetInfo()195 uno::Reference< beans::XPropertySetInfo > SAL_CALL ScatterChartTypeTemplate::getPropertySetInfo()
196     throw (uno::RuntimeException)
197 {
198     return *StaticScatterChartTypeTemplateInfo::get();
199 }
200 
getDimension() const201 sal_Int32 ScatterChartTypeTemplate::getDimension() const
202 {
203     return m_nDim;
204 }
205 
getStackMode(sal_Int32) const206 StackMode ScatterChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const
207 {
208     if( m_nDim == 3 )
209         return StackMode_Z_STACKED;
210     return StackMode_NONE;
211 }
212 
applyStyle(const Reference<chart2::XDataSeries> & xSeries,::sal_Int32 nChartTypeIndex,::sal_Int32 nSeriesIndex,::sal_Int32 nSeriesCount)213 void SAL_CALL ScatterChartTypeTemplate::applyStyle(
214     const Reference< chart2::XDataSeries >& xSeries,
215     ::sal_Int32 nChartTypeIndex,
216     ::sal_Int32 nSeriesIndex,
217     ::sal_Int32 nSeriesCount )
218     throw (uno::RuntimeException)
219 {
220     ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount );
221 
222     try
223     {
224         Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW );
225 
226         DataSeriesHelper::switchSymbolsOnOrOff( xProp, m_bHasSymbols, nSeriesIndex );
227         DataSeriesHelper::switchLinesOnOrOff( xProp, m_bHasLines );
228         DataSeriesHelper::makeLinesThickOrThin( xProp, m_nDim==2 );
229         if( m_nDim==3 )
230             DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) );
231     }
232     catch( uno::Exception & ex )
233     {
234         ASSERT_EXCEPTION( ex );
235     }
236 }
237 
238 // ____ XChartTypeTemplate ____
supportsCategories()239 sal_Bool SAL_CALL ScatterChartTypeTemplate::supportsCategories()
240     throw (uno::RuntimeException)
241 {
242     return sal_False;
243 }
244 
matchesTemplate(const Reference<chart2::XDiagram> & xDiagram,sal_Bool bAdaptProperties)245 sal_Bool SAL_CALL ScatterChartTypeTemplate::matchesTemplate(
246     const Reference< chart2::XDiagram >& xDiagram,
247     sal_Bool bAdaptProperties )
248     throw (uno::RuntimeException)
249 {
250     sal_Bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties );
251 
252     // check symbol-style and line-style
253     // for a template with symbols (or with lines) it is ok, if there is at least one series
254     // with symbols (or with lines)
255     if( bResult )
256     {
257         bool bSymbolFound = false;
258         bool bLineFound = false;
259 
260         ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
261             DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
262 
263         for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
264                  aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
265         {
266             try
267             {
268                 chart2::Symbol aSymbProp;
269                 drawing::LineStyle eLineStyle;
270                 Reference< beans::XPropertySet > xProp( *aIt, uno::UNO_QUERY_THROW );
271 
272                 bool bCurrentHasSymbol = (xProp->getPropertyValue( C2U( "Symbol" )) >>= aSymbProp) &&
273                     (aSymbProp.Style != chart2::SymbolStyle_NONE);
274 
275                 if( bCurrentHasSymbol )
276                     bSymbolFound = true;
277 
278                 if( bCurrentHasSymbol && (!m_bHasSymbols) )
279                 {
280                     bResult = false;
281                     break;
282                 }
283 
284                 bool bCurrentHasLine = (xProp->getPropertyValue( C2U( "LineStyle" )) >>= eLineStyle) &&
285                     ( eLineStyle != drawing::LineStyle_NONE );
286 
287                 if( bCurrentHasLine )
288                     bLineFound = true;
289 
290                 if( bCurrentHasLine && (!m_bHasLines) )
291                 {
292                     bResult = false;
293                     break;
294                 }
295             }
296             catch( uno::Exception & ex )
297             {
298                 ASSERT_EXCEPTION( ex );
299             }
300         }
301 
302         if(bResult)
303         {
304             if( !bLineFound && m_bHasLines && bSymbolFound )
305                 bResult = false;
306             else if( !bSymbolFound && m_bHasSymbols && bLineFound )
307                 bResult = false;
308             else if( !bLineFound && !bSymbolFound )
309                 return m_bHasLines && m_bHasSymbols;
310         }
311     }
312 
313     // adapt curve style, spline order and resolution
314     if( bResult && bAdaptProperties )
315     {
316         try
317         {
318             uno::Reference< beans::XPropertySet > xChartTypeProp(
319                 DiagramHelper::getChartTypeByIndex( xDiagram, 0 ),
320                 uno::UNO_QUERY_THROW );
321             setFastPropertyValue_NoBroadcast( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, xChartTypeProp->getPropertyValue(C2U("CurveStyle" )) );
322             setFastPropertyValue_NoBroadcast( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION, xChartTypeProp->getPropertyValue(C2U("CurveResolution" )) );
323             setFastPropertyValue_NoBroadcast( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER, xChartTypeProp->getPropertyValue(C2U("SplineOrder" )) );
324         }
325         catch( uno::Exception & ex )
326         {
327             ASSERT_EXCEPTION( ex );
328         }
329     }
330 
331     return bResult;
332 }
333 
getChartTypeForIndex(sal_Int32)334 Reference< chart2::XChartType > ScatterChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ )
335 {
336     Reference< chart2::XChartType > xResult;
337 
338     try
339     {
340         Reference< lang::XMultiServiceFactory > xFact(
341             GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
342         xResult.set( xFact->createInstance(
343                          CHART2_SERVICE_NAME_CHARTTYPE_SCATTER ), uno::UNO_QUERY_THROW );
344 
345         Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY );
346         if( xCTProp.is())
347         {
348             xCTProp->setPropertyValue(
349                 C2U( "CurveStyle" ), getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE ));
350             xCTProp->setPropertyValue(
351                 C2U( "CurveResolution" ), getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION ));
352             xCTProp->setPropertyValue(
353                 C2U( "SplineOrder" ), getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER ));
354         }
355     }
356     catch( uno::Exception & ex )
357     {
358         ASSERT_EXCEPTION( ex );
359     }
360 
361     return xResult;
362 }
363 
getChartTypeForNewSeries(const uno::Sequence<Reference<chart2::XChartType>> & aFormerlyUsedChartTypes)364 Reference< chart2::XChartType > SAL_CALL ScatterChartTypeTemplate::getChartTypeForNewSeries(
365         const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes )
366     throw (uno::RuntimeException)
367 {
368     Reference< chart2::XChartType > xResult;
369 
370     try
371     {
372         Reference< lang::XMultiServiceFactory > xFact(
373             GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW );
374         xResult.set( xFact->createInstance(
375                          CHART2_SERVICE_NAME_CHARTTYPE_SCATTER ), uno::UNO_QUERY_THROW );
376 
377         ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem( aFormerlyUsedChartTypes, xResult );
378 
379         Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY );
380         if( xCTProp.is())
381         {
382             xCTProp->setPropertyValue(
383                 C2U( "CurveStyle" ), getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE ));
384             xCTProp->setPropertyValue(
385                 C2U( "CurveResolution" ), getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION ));
386             xCTProp->setPropertyValue(
387                 C2U( "SplineOrder" ), getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER ));
388         }
389     }
390     catch( uno::Exception & ex )
391     {
392         ASSERT_EXCEPTION( ex );
393     }
394 
395     return xResult;
396 }
397 
getDataInterpreter()398 Reference< chart2::XDataInterpreter > SAL_CALL ScatterChartTypeTemplate::getDataInterpreter()
399     throw (uno::RuntimeException)
400 {
401     if( ! m_xDataInterpreter.is())
402         m_xDataInterpreter.set( new XYDataInterpreter( GetComponentContext()) );
403 
404     return m_xDataInterpreter;
405 }
406 
407 // ----------------------------------------
408 
getSupportedServiceNames_Static()409 Sequence< OUString > ScatterChartTypeTemplate::getSupportedServiceNames_Static()
410 {
411     Sequence< OUString > aServices( 2 );
412     aServices[ 0 ] = lcl_aServiceName;
413     aServices[ 1 ] = C2U( "com.sun.star.chart2.ChartTypeTemplate" );
414     return aServices;
415 }
416 
417 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
418 APPHELPER_XSERVICEINFO_IMPL( ScatterChartTypeTemplate, lcl_aServiceName );
419 
420 IMPLEMENT_FORWARD_XINTERFACE2( ScatterChartTypeTemplate, ChartTypeTemplate, OPropertySet )
421 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScatterChartTypeTemplate, ChartTypeTemplate, OPropertySet )
422 
423 } //  namespace chart
424