1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "RegressionCurveModel.hxx"
31 #include "macros.hxx"
32 #include "LineProperties.hxx"
33 #include "RegressionCurveHelper.hxx"
34 #include "RegressionCalculationHelper.hxx"
35 #include "RegressionEquation.hxx"
36 #include "ContainerHelper.hxx"
37 #include "CloneHelper.hxx"
38 #include "PropertyHelper.hxx"
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <rtl/math.hxx>
41 #include <rtl/ustrbuf.hxx>
42 
43 using namespace ::com::sun::star;
44 
45 using ::rtl::OUString;
46 using ::rtl::OUStringBuffer;
47 using ::com::sun::star::beans::Property;
48 using ::osl::MutexGuard;
49 
50 namespace
51 {
52 static const OUString lcl_aImplementationName_MeanValue(
53     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.MeanValueRegressionCurve" ));
54 static const OUString lcl_aImplementationName_Linear(
55     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.LinearRegressionCurve" ));
56 static const OUString lcl_aImplementationName_Logarithmic(
57     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.LogarithmicRegressionCurve" ));
58 static const OUString lcl_aImplementationName_Exponential(
59     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.ExponentialRegressionCurve" ));
60 static const OUString lcl_aImplementationName_Potential(
61     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.PotentialRegressionCurve" ));
62 
63 static const OUString lcl_aServiceName(
64     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.RegressionCurve" ));
65 
66 struct StaticXXXDefaults_Initializer
67 {
68     ::chart::tPropertyValueMap* operator()()
69     {
70         static ::chart::tPropertyValueMap aStaticDefaults;
71         lcl_AddDefaultsToMap( aStaticDefaults );
72         return &aStaticDefaults;
73     }
74 private:
75     void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap )
76     {
77         ::chart::LineProperties::AddDefaultsToMap( rOutMap );
78     }
79 };
80 
81 struct StaticXXXDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticXXXDefaults_Initializer >
82 {
83 };
84 
85 struct StaticRegressionCurveInfoHelper_Initializer
86 {
87     ::cppu::OPropertyArrayHelper* operator()()
88     {
89         static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() );
90         return &aPropHelper;
91     }
92 
93 private:
94     uno::Sequence< Property > lcl_GetPropertySequence()
95     {
96         ::std::vector< ::com::sun::star::beans::Property > aProperties;
97         ::chart::LineProperties::AddPropertiesToVector( aProperties );
98 
99         ::std::sort( aProperties.begin(), aProperties.end(),
100                      ::chart::PropertyNameLess() );
101 
102         return ::chart::ContainerHelper::ContainerToSequence( aProperties );
103     }
104 };
105 
106 struct StaticRegressionCurveInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticRegressionCurveInfoHelper_Initializer >
107 {
108 };
109 
110 struct StaticRegressionCurveInfo_Initializer
111 {
112     uno::Reference< beans::XPropertySetInfo >* operator()()
113     {
114         static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
115             ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticRegressionCurveInfoHelper::get() ) );
116         return &xPropertySetInfo;
117     }
118 };
119 
120 struct StaticRegressionCurveInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticRegressionCurveInfo_Initializer >
121 {
122 };
123 
124 } // anonymous namespace
125 
126 namespace chart
127 {
128 
129 RegressionCurveModel::RegressionCurveModel(
130     uno::Reference< uno::XComponentContext > const & xContext,
131     tCurveType eCurveType ) :
132         ::property::OPropertySet( m_aMutex ),
133     m_xContext( xContext ),
134     m_eRegressionCurveType( eCurveType ),
135         m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()),
136         m_xEquationProperties( new RegressionEquation( xContext ))
137 {
138     // set 0 line width (default) hard, so that it is always written to XML,
139     // because the old implementation uses different defaults
140     setFastPropertyValue_NoBroadcast(
141         LineProperties::PROP_LINE_WIDTH, uno::makeAny( sal_Int32( 0 )));
142     ModifyListenerHelper::addListener( m_xEquationProperties, m_xModifyEventForwarder );
143 }
144 
145 RegressionCurveModel::RegressionCurveModel( const RegressionCurveModel & rOther ) :
146         MutexContainer(),
147         impl::RegressionCurveModel_Base(),
148         ::property::OPropertySet( rOther, m_aMutex ),
149     m_xContext( rOther.m_xContext ),
150     m_eRegressionCurveType( rOther.m_eRegressionCurveType ),
151     m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
152 {
153     m_xEquationProperties.set( CloneHelper::CreateRefClone< uno::Reference< beans::XPropertySet > >()( rOther.m_xEquationProperties ));
154     ModifyListenerHelper::addListener( m_xEquationProperties, m_xModifyEventForwarder );
155 }
156 
157 RegressionCurveModel::~RegressionCurveModel()
158 {}
159 
160 // ____ XRegressionCurve ____
161 uno::Reference< chart2::XRegressionCurveCalculator > SAL_CALL
162     RegressionCurveModel::getCalculator()
163     throw (uno::RuntimeException)
164 {
165     return RegressionCurveHelper::createRegressionCurveCalculatorByServiceName( getServiceName());
166 }
167 
168 uno::Reference< beans::XPropertySet > SAL_CALL RegressionCurveModel::getEquationProperties()
169     throw (uno::RuntimeException)
170 {
171     return m_xEquationProperties;
172 }
173 
174 void SAL_CALL RegressionCurveModel::setEquationProperties( const uno::Reference< beans::XPropertySet >& xEquationProperties )
175     throw (uno::RuntimeException)
176 {
177     if( xEquationProperties.is())
178     {
179         if( m_xEquationProperties.is())
180             ModifyListenerHelper::removeListener( m_xEquationProperties, m_xModifyEventForwarder );
181 
182         m_xEquationProperties.set( xEquationProperties );
183         ModifyListenerHelper::addListener( m_xEquationProperties, m_xModifyEventForwarder );
184         fireModifyEvent();
185     }
186 }
187 
188 // ____ XServiceName ____
189 ::rtl::OUString SAL_CALL RegressionCurveModel::getServiceName()
190     throw (uno::RuntimeException)
191 {
192     switch( m_eRegressionCurveType )
193     {
194         case CURVE_TYPE_MEAN_VALUE:
195             return C2U( "com.sun.star.chart2.MeanValueRegressionCurve" );
196         case CURVE_TYPE_LINEAR:
197             return C2U( "com.sun.star.chart2.LinearRegressionCurve" );
198         case CURVE_TYPE_LOGARITHM:
199             return C2U( "com.sun.star.chart2.LogarithmicRegressionCurve" );
200         case CURVE_TYPE_EXPONENTIAL:
201             return C2U( "com.sun.star.chart2.ExponentialRegressionCurve" );
202         case CURVE_TYPE_POWER:
203             return C2U( "com.sun.star.chart2.PotentialRegressionCurve" );
204     }
205 
206     return ::rtl::OUString();
207 }
208 
209 // ____ XModifyBroadcaster ____
210 void SAL_CALL RegressionCurveModel::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
211     throw (uno::RuntimeException)
212 {
213     try
214     {
215         uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
216         xBroadcaster->addModifyListener( aListener );
217     }
218     catch( const uno::Exception & ex )
219     {
220         ASSERT_EXCEPTION( ex );
221     }
222 }
223 
224 void SAL_CALL RegressionCurveModel::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
225     throw (uno::RuntimeException)
226 {
227     try
228     {
229         uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
230         xBroadcaster->removeModifyListener( aListener );
231     }
232     catch( const uno::Exception & ex )
233     {
234         ASSERT_EXCEPTION( ex );
235     }
236 }
237 
238 // ____ XModifyListener ____
239 void SAL_CALL RegressionCurveModel::modified( const lang::EventObject& aEvent )
240     throw (uno::RuntimeException)
241 {
242     m_xModifyEventForwarder->modified( aEvent );
243 }
244 
245 // ____ XEventListener (base of XModifyListener) ____
246 void SAL_CALL RegressionCurveModel::disposing( const lang::EventObject& /* Source */ )
247     throw (uno::RuntimeException)
248 {
249     // nothing
250 }
251 
252 // ____ OPropertySet ____
253 void RegressionCurveModel::firePropertyChangeEvent()
254 {
255     fireModifyEvent();
256 }
257 
258 void RegressionCurveModel::fireModifyEvent()
259 {
260     m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
261 }
262 
263 // ================================================================================
264 
265 // ____ OPropertySet ____
266 uno::Any RegressionCurveModel::GetDefaultValue( sal_Int32 nHandle ) const
267     throw(beans::UnknownPropertyException)
268 {
269     const tPropertyValueMap& rStaticDefaults = *StaticXXXDefaults::get();
270     tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
271     if( aFound == rStaticDefaults.end() )
272         return uno::Any();
273     return (*aFound).second;
274 }
275 
276 ::cppu::IPropertyArrayHelper & SAL_CALL RegressionCurveModel::getInfoHelper()
277 {
278     return *StaticRegressionCurveInfoHelper::get();
279 }
280 
281 // ____ XPropertySet ____
282 uno::Reference< beans::XPropertySetInfo > SAL_CALL RegressionCurveModel::getPropertySetInfo()
283     throw (uno::RuntimeException)
284 {
285     return *StaticRegressionCurveInfo::get();
286 }
287 
288 // ================================================================================
289 
290 // needed by MSC compiler
291 using impl::RegressionCurveModel_Base;
292 
293 IMPLEMENT_FORWARD_XINTERFACE2( RegressionCurveModel, RegressionCurveModel_Base, OPropertySet )
294 IMPLEMENT_FORWARD_XTYPEPROVIDER2( RegressionCurveModel, RegressionCurveModel_Base, OPropertySet )
295 
296 
297 
298 // implementations
299 
300 // --------------------------------------------------------------------------------
301 
302 MeanValueRegressionCurve::MeanValueRegressionCurve(
303     const uno::Reference< uno::XComponentContext > & xContext )
304         : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_MEAN_VALUE )
305 {}
306 MeanValueRegressionCurve::MeanValueRegressionCurve(
307     const MeanValueRegressionCurve & rOther ) :
308         RegressionCurveModel( rOther )
309 {}
310 MeanValueRegressionCurve::~MeanValueRegressionCurve()
311 {}
312 uno::Sequence< ::rtl::OUString > MeanValueRegressionCurve::getSupportedServiceNames_Static()
313 {
314     uno::Sequence< ::rtl::OUString > aServices( 2 );
315     aServices[ 0 ] = lcl_aServiceName;
316     aServices[ 1 ] = C2U( "com.sun.star.chart2.MeanValueRegressionCurve" );
317     return aServices;
318 }
319 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
320 APPHELPER_XSERVICEINFO_IMPL( MeanValueRegressionCurve, lcl_aImplementationName_MeanValue );
321 
322 uno::Reference< util::XCloneable > SAL_CALL MeanValueRegressionCurve::createClone()
323     throw (uno::RuntimeException)
324 {
325     return uno::Reference< util::XCloneable >( new MeanValueRegressionCurve( *this ));
326 }
327 
328 // --------------------------------------------------------------------------------
329 
330 LinearRegressionCurve::LinearRegressionCurve(
331     const uno::Reference< uno::XComponentContext > & xContext )
332         : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_LINEAR )
333 {}
334 LinearRegressionCurve::LinearRegressionCurve(
335     const LinearRegressionCurve & rOther ) :
336         RegressionCurveModel( rOther )
337 {}
338 LinearRegressionCurve::~LinearRegressionCurve()
339 {}
340 uno::Sequence< ::rtl::OUString > LinearRegressionCurve::getSupportedServiceNames_Static()
341 {
342     uno::Sequence< ::rtl::OUString > aServices( 2 );
343     aServices[ 0 ] = lcl_aServiceName;
344     aServices[ 1 ] = C2U( "com.sun.star.chart2.LinearRegressionCurve" );
345     return aServices;
346 }
347 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
348 APPHELPER_XSERVICEINFO_IMPL( LinearRegressionCurve, lcl_aImplementationName_Linear );
349 
350 uno::Reference< util::XCloneable > SAL_CALL LinearRegressionCurve::createClone()
351     throw (uno::RuntimeException)
352 {
353     return uno::Reference< util::XCloneable >( new LinearRegressionCurve( *this ));
354 }
355 
356 // --------------------------------------------------------------------------------
357 
358 LogarithmicRegressionCurve::LogarithmicRegressionCurve(
359     const uno::Reference< uno::XComponentContext > & xContext )
360         : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_LOGARITHM )
361 {}
362 LogarithmicRegressionCurve::LogarithmicRegressionCurve(
363     const LogarithmicRegressionCurve & rOther ) :
364         RegressionCurveModel( rOther )
365 {}
366 LogarithmicRegressionCurve::~LogarithmicRegressionCurve()
367 {}
368 uno::Sequence< ::rtl::OUString > LogarithmicRegressionCurve::getSupportedServiceNames_Static()
369 {
370     uno::Sequence< ::rtl::OUString > aServices( 2 );
371     aServices[ 0 ] = lcl_aServiceName;
372     aServices[ 1 ] = C2U( "com.sun.star.chart2.LogarithmicRegressionCurve" );
373     return aServices;
374 }
375 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
376 APPHELPER_XSERVICEINFO_IMPL( LogarithmicRegressionCurve, lcl_aImplementationName_Logarithmic );
377 
378 uno::Reference< util::XCloneable > SAL_CALL LogarithmicRegressionCurve::createClone()
379     throw (uno::RuntimeException)
380 {
381     return uno::Reference< util::XCloneable >( new LogarithmicRegressionCurve( *this ));
382 }
383 
384 // --------------------------------------------------------------------------------
385 
386 ExponentialRegressionCurve::ExponentialRegressionCurve(
387     const uno::Reference< uno::XComponentContext > & xContext )
388         : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_EXPONENTIAL )
389 {}
390 ExponentialRegressionCurve::ExponentialRegressionCurve(
391     const ExponentialRegressionCurve & rOther ) :
392         RegressionCurveModel( rOther )
393 {}
394 ExponentialRegressionCurve::~ExponentialRegressionCurve()
395 {}
396 uno::Sequence< ::rtl::OUString > ExponentialRegressionCurve::getSupportedServiceNames_Static()
397 {
398     uno::Sequence< ::rtl::OUString > aServices( 2 );
399     aServices[ 0 ] = lcl_aServiceName;
400     aServices[ 1 ] = C2U( "com.sun.star.chart2.ExponentialRegressionCurve" );
401     return aServices;
402 }
403 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
404 APPHELPER_XSERVICEINFO_IMPL( ExponentialRegressionCurve, lcl_aImplementationName_Exponential );
405 
406 uno::Reference< util::XCloneable > SAL_CALL ExponentialRegressionCurve::createClone()
407     throw (uno::RuntimeException)
408 {
409     return uno::Reference< util::XCloneable >( new ExponentialRegressionCurve( *this ));
410 }
411 
412 // --------------------------------------------------------------------------------
413 
414 PotentialRegressionCurve::PotentialRegressionCurve(
415     const uno::Reference< uno::XComponentContext > & xContext )
416         : RegressionCurveModel( xContext, RegressionCurveModel::CURVE_TYPE_POWER )
417 {}
418 PotentialRegressionCurve::PotentialRegressionCurve(
419     const PotentialRegressionCurve & rOther ) :
420         RegressionCurveModel( rOther )
421 {}
422 PotentialRegressionCurve::~PotentialRegressionCurve()
423 {}
424 uno::Sequence< ::rtl::OUString > PotentialRegressionCurve::getSupportedServiceNames_Static()
425 {
426     uno::Sequence< ::rtl::OUString > aServices( 2 );
427     aServices[ 0 ] = lcl_aServiceName;
428     aServices[ 1 ] = C2U( "com.sun.star.chart2.PotentialRegressionCurve" );
429     return aServices;
430 }
431 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
432 APPHELPER_XSERVICEINFO_IMPL( PotentialRegressionCurve, lcl_aImplementationName_Potential );
433 
434 uno::Reference< util::XCloneable > SAL_CALL PotentialRegressionCurve::createClone()
435     throw (uno::RuntimeException)
436 {
437     return uno::Reference< util::XCloneable >( new PotentialRegressionCurve( *this ));
438 }
439 
440 
441 } //  namespace chart
442