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 
27 #include "BaseCoordinateSystem.hxx"
28 #include "macros.hxx"
29 #include "PropertyHelper.hxx"
30 #include "UserDefinedProperties.hxx"
31 #include "ContainerHelper.hxx"
32 #include "CloneHelper.hxx"
33 #include "Axis.hxx"
34 #include "AxisHelper.hxx"
35 #include <com/sun/star/chart2/AxisType.hpp>
36 
37 #include <algorithm>
38 
39 #if OSL_DEBUG_LEVEL > 1
40 #include <rtl/math.hxx>
41 #endif
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43 
44 using namespace ::com::sun::star;
45 using ::com::sun::star::uno::Reference;
46 using ::com::sun::star::uno::Sequence;
47 using ::rtl::OUString;
48 using ::com::sun::star::beans::Property;
49 
50 namespace
51 {
52 enum
53 {
54     PROP_COORDINATESYSTEM_SWAPXANDYAXIS
55 };
56 
lcl_AddPropertiesToVector(::std::vector<Property> & rOutProperties)57 void lcl_AddPropertiesToVector(
58     ::std::vector< Property > & rOutProperties )
59 {
60     rOutProperties.push_back(
61         Property( C2U( "SwapXAndYAxis" ),
62                   PROP_COORDINATESYSTEM_SWAPXANDYAXIS,
63                   ::getBooleanCppuType(),
64                   beans::PropertyAttribute::BOUND
65                   | beans::PropertyAttribute::MAYBEVOID ));
66 }
67 
68 struct StaticCooSysDefaults_Initializer
69 {
operator ()__anon03da8d0f0111::StaticCooSysDefaults_Initializer70     ::chart::tPropertyValueMap* operator()()
71     {
72         static ::chart::tPropertyValueMap aStaticDefaults;
73         lcl_AddDefaultsToMap( aStaticDefaults );
74         return &aStaticDefaults;
75     }
76 private:
lcl_AddDefaultsToMap__anon03da8d0f0111::StaticCooSysDefaults_Initializer77     void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap )
78     {
79         ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_COORDINATESYSTEM_SWAPXANDYAXIS, false );
80     }
81 };
82 
83 struct StaticCooSysDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticCooSysDefaults_Initializer >
84 {
85 };
86 
87 struct StaticCooSysInfoHelper_Initializer
88 {
operator ()__anon03da8d0f0111::StaticCooSysInfoHelper_Initializer89     ::cppu::OPropertyArrayHelper* operator()()
90     {
91         static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() );
92         return &aPropHelper;
93     }
94 
95 private:
lcl_GetPropertySequence__anon03da8d0f0111::StaticCooSysInfoHelper_Initializer96     Sequence< Property > lcl_GetPropertySequence()
97     {
98         ::std::vector< ::com::sun::star::beans::Property > aProperties;
99         lcl_AddPropertiesToVector( aProperties );
100         ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties );
101 
102         ::std::sort( aProperties.begin(), aProperties.end(),
103                      ::chart::PropertyNameLess() );
104 
105         return ::chart::ContainerHelper::ContainerToSequence( aProperties );
106     }
107 };
108 
109 struct StaticCooSysInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticCooSysInfoHelper_Initializer >
110 {
111 };
112 
113 struct StaticCooSysInfo_Initializer
114 {
operator ()__anon03da8d0f0111::StaticCooSysInfo_Initializer115     uno::Reference< beans::XPropertySetInfo >* operator()()
116     {
117         static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
118             ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticCooSysInfoHelper::get() ) );
119         return &xPropertySetInfo;
120     }
121 };
122 
123 struct StaticCooSysInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticCooSysInfo_Initializer >
124 {
125 };
126 
127 } // anonymous namespace
128 
129 namespace chart
130 {
131 
BaseCoordinateSystem(const Reference<uno::XComponentContext> & xContext,sal_Int32 nDimensionCount,sal_Bool bSwapXAndYAxis)132 BaseCoordinateSystem::BaseCoordinateSystem(
133     const Reference< uno::XComponentContext > & xContext,
134     sal_Int32 nDimensionCount /* = 2 */,
135     sal_Bool bSwapXAndYAxis /* = sal_False */ ) :
136         ::property::OPropertySet( m_aMutex ),
137         m_xContext( xContext ),
138         m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()),
139         m_nDimensionCount( nDimensionCount )
140  {
141     m_aAllAxis.resize( m_nDimensionCount );
142     for( sal_Int32 nN=0; nN<m_nDimensionCount; nN++ )
143     {
144         m_aAllAxis[nN].resize( 1 );
145         Reference< chart2::XAxis > xAxis( new Axis(m_xContext) );
146         m_aAllAxis[nN][0] = xAxis;
147 
148         ModifyListenerHelper::addListenerToAllElements( m_aAllAxis[nN], m_xModifyEventForwarder );
149         chart2::ScaleData aScaleData( xAxis->getScaleData() );
150         if(nN==0)
151         {
152             aScaleData.AxisType = chart2::AxisType::CATEGORY;
153         }
154         else if( nN==1)
155         {
156             aScaleData.AxisType = chart2::AxisType::REALNUMBER;
157         }
158         else if( nN==2)
159         {
160             aScaleData.AxisType = chart2::AxisType::SERIES;
161         }
162         xAxis->setScaleData( aScaleData );
163     }
164 
165     m_aOrigin.realloc( m_nDimensionCount );
166     for( sal_Int32 i = 0; i < m_nDimensionCount; ++i )
167         m_aOrigin[ i ] = uno::makeAny( double( 0.0 ) );
168 
169     setFastPropertyValue_NoBroadcast( PROP_COORDINATESYSTEM_SWAPXANDYAXIS, uno::makeAny( sal_Bool( bSwapXAndYAxis )));
170 }
171 
172 // explicit
BaseCoordinateSystem(const BaseCoordinateSystem & rSource)173 BaseCoordinateSystem::BaseCoordinateSystem(
174     const BaseCoordinateSystem & rSource ) :
175         impl::BaseCoordinateSystem_Base(),
176         MutexContainer(),
177         ::property::OPropertySet( rSource, m_aMutex ),
178     m_xContext( rSource.m_xContext ),
179     m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()),
180     m_nDimensionCount( rSource.m_nDimensionCount ),
181     m_aOrigin( rSource.m_aOrigin )
182 {
183     m_aAllAxis.resize(rSource.m_aAllAxis.size());
184     tAxisVecVecType::size_type nN=0;
185     for( nN=0; nN<m_aAllAxis.size(); nN++ )
186         CloneHelper::CloneRefVector< Reference< chart2::XAxis > >( rSource.m_aAllAxis[nN], m_aAllAxis[nN] );
187     CloneHelper::CloneRefVector< Reference< chart2::XChartType > >( rSource.m_aChartTypes, m_aChartTypes );
188 
189     for( nN=0; nN<m_aAllAxis.size(); nN++ )
190         ModifyListenerHelper::addListenerToAllElements( m_aAllAxis[nN], m_xModifyEventForwarder );
191     ModifyListenerHelper::addListenerToAllElements( m_aChartTypes, m_xModifyEventForwarder );
192 }
193 
~BaseCoordinateSystem()194 BaseCoordinateSystem::~BaseCoordinateSystem()
195 {
196     try
197     {
198         for( tAxisVecVecType::size_type nN=0; nN<m_aAllAxis.size(); nN++ )
199             ModifyListenerHelper::removeListenerFromAllElements( m_aAllAxis[nN], m_xModifyEventForwarder );
200         ModifyListenerHelper::removeListenerFromAllElements( m_aChartTypes, m_xModifyEventForwarder );
201     }
202     catch( const uno::Exception & ex )
203     {
204         ASSERT_EXCEPTION( ex );
205     }
206 }
207 
208 // ____ XCoordinateSystem ____
getDimension()209 sal_Int32 SAL_CALL BaseCoordinateSystem::getDimension()
210     throw (uno::RuntimeException)
211 {
212     return m_nDimensionCount;
213 }
214 
setAxisByDimension(sal_Int32 nDimensionIndex,const Reference<chart2::XAxis> & xAxis,sal_Int32 nIndex)215 void SAL_CALL BaseCoordinateSystem::setAxisByDimension(
216     sal_Int32 nDimensionIndex,
217     const Reference< chart2::XAxis >& xAxis,
218     sal_Int32 nIndex )
219     throw (lang::IndexOutOfBoundsException,
220            uno::RuntimeException)
221 {
222     if( nDimensionIndex < 0 || nDimensionIndex >= getDimension() )
223         throw lang::IndexOutOfBoundsException();
224 
225     if( nIndex < 0 )
226         throw lang::IndexOutOfBoundsException();
227 
228     if( m_aAllAxis[ nDimensionIndex ].size() < static_cast< tAxisVecVecType::size_type >( nIndex+1 ))
229     {
230         m_aAllAxis[ nDimensionIndex ].resize( nIndex+1 );
231         m_aAllAxis[ nDimensionIndex ][nIndex] = 0;
232     }
233 
234     Reference< chart2::XAxis > xOldAxis( m_aAllAxis[ nDimensionIndex ][nIndex] );
235     if( xOldAxis.is())
236         ModifyListenerHelper::removeListener( xOldAxis, m_xModifyEventForwarder );
237     m_aAllAxis[ nDimensionIndex ][nIndex] = xAxis;
238     if( xAxis.is())
239         ModifyListenerHelper::addListener( xAxis, m_xModifyEventForwarder );
240     fireModifyEvent();
241 }
242 
getAxisByDimension(sal_Int32 nDimensionIndex,sal_Int32 nAxisIndex)243 Reference< chart2::XAxis > SAL_CALL BaseCoordinateSystem::getAxisByDimension(
244             sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
245     throw (lang::IndexOutOfBoundsException,
246            uno::RuntimeException)
247 {
248     if( nDimensionIndex < 0 || nDimensionIndex >= getDimension() )
249         throw lang::IndexOutOfBoundsException();
250 
251     OSL_ASSERT( m_aAllAxis.size() == static_cast< size_t >( getDimension()));
252 
253     if( nAxisIndex < 0 || nAxisIndex > this->getMaximumAxisIndexByDimension(nDimensionIndex) )
254         throw lang::IndexOutOfBoundsException();
255 
256     return m_aAllAxis[ nDimensionIndex ][nAxisIndex];
257 }
258 
getMaximumAxisIndexByDimension(sal_Int32 nDimensionIndex)259 sal_Int32 SAL_CALL BaseCoordinateSystem::getMaximumAxisIndexByDimension( sal_Int32 nDimensionIndex )
260         throw (lang::IndexOutOfBoundsException,
261            uno::RuntimeException)
262 {
263     if( nDimensionIndex < 0 || nDimensionIndex >= getDimension() )
264         throw lang::IndexOutOfBoundsException();
265 
266     OSL_ASSERT( m_aAllAxis.size() == static_cast< size_t >( getDimension()));
267 
268     sal_Int32 nRet = m_aAllAxis[ nDimensionIndex ].size();
269     if(nRet)
270         nRet-=1;
271 
272     return nRet;
273 }
274 
275 // ____ XChartTypeContainer ____
addChartType(const Reference<chart2::XChartType> & aChartType)276 void SAL_CALL BaseCoordinateSystem::addChartType( const Reference< chart2::XChartType >& aChartType )
277     throw (lang::IllegalArgumentException,
278            uno::RuntimeException)
279 {
280     if( ::std::find( m_aChartTypes.begin(), m_aChartTypes.end(), aChartType )
281         != m_aChartTypes.end())
282         throw lang::IllegalArgumentException();
283 
284     m_aChartTypes.push_back( aChartType );
285     ModifyListenerHelper::addListener( aChartType, m_xModifyEventForwarder );
286     fireModifyEvent();
287 }
288 
removeChartType(const Reference<chart2::XChartType> & aChartType)289 void SAL_CALL BaseCoordinateSystem::removeChartType( const Reference< chart2::XChartType >& aChartType )
290     throw (container::NoSuchElementException,
291            uno::RuntimeException)
292 {
293     ::std::vector< uno::Reference< chart2::XChartType > >::iterator
294           aIt( ::std::find( m_aChartTypes.begin(), m_aChartTypes.end(), aChartType ));
295     if( aIt == m_aChartTypes.end())
296         throw container::NoSuchElementException(
297             C2U( "The given chart type is no element of the container" ),
298             static_cast< uno::XWeak * >( this ));
299 
300     m_aChartTypes.erase( aIt );
301     ModifyListenerHelper::removeListener( aChartType, m_xModifyEventForwarder );
302     fireModifyEvent();
303 }
304 
getChartTypes()305 Sequence< Reference< chart2::XChartType > > SAL_CALL BaseCoordinateSystem::getChartTypes()
306     throw (uno::RuntimeException)
307 {
308     return ContainerHelper::ContainerToSequence( m_aChartTypes );
309 }
310 
setChartTypes(const Sequence<Reference<chart2::XChartType>> & aChartTypes)311 void SAL_CALL BaseCoordinateSystem::setChartTypes( const Sequence< Reference< chart2::XChartType > >& aChartTypes )
312     throw (lang::IllegalArgumentException,
313            uno::RuntimeException)
314 {
315     ModifyListenerHelper::removeListenerFromAllElements( m_aChartTypes, m_xModifyEventForwarder );
316     m_aChartTypes = ContainerHelper::SequenceToVector( aChartTypes );
317     ModifyListenerHelper::addListenerToAllElements( m_aChartTypes, m_xModifyEventForwarder );
318     fireModifyEvent();
319 }
320 
321 // ____ XModifyBroadcaster ____
addModifyListener(const Reference<util::XModifyListener> & aListener)322 void SAL_CALL BaseCoordinateSystem::addModifyListener( const Reference< util::XModifyListener >& aListener )
323     throw (uno::RuntimeException)
324 {
325     try
326     {
327         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
328         xBroadcaster->addModifyListener( aListener );
329     }
330     catch( const uno::Exception & ex )
331     {
332         ASSERT_EXCEPTION( ex );
333     }
334 }
335 
removeModifyListener(const Reference<util::XModifyListener> & aListener)336 void SAL_CALL BaseCoordinateSystem::removeModifyListener( const Reference< util::XModifyListener >& aListener )
337     throw (uno::RuntimeException)
338 {
339     try
340     {
341         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
342         xBroadcaster->removeModifyListener( aListener );
343     }
344     catch( const uno::Exception & ex )
345     {
346         ASSERT_EXCEPTION( ex );
347     }
348 }
349 
350 // ____ XModifyListener ____
modified(const lang::EventObject & aEvent)351 void SAL_CALL BaseCoordinateSystem::modified( const lang::EventObject& aEvent )
352     throw (uno::RuntimeException)
353 {
354     m_xModifyEventForwarder->modified( aEvent );
355 }
356 
357 // ____ XEventListener (base of XModifyListener) ____
disposing(const lang::EventObject &)358 void SAL_CALL BaseCoordinateSystem::disposing( const lang::EventObject& /* Source */ )
359     throw (uno::RuntimeException)
360 {
361     // nothing
362 }
363 
364 // ____ OPropertySet ____
firePropertyChangeEvent()365 void BaseCoordinateSystem::firePropertyChangeEvent()
366 {
367     fireModifyEvent();
368 }
369 
fireModifyEvent()370 void BaseCoordinateSystem::fireModifyEvent()
371 {
372     m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
373 }
374 
375 
376 // ____ OPropertySet ____
GetDefaultValue(sal_Int32 nHandle) const377 uno::Any BaseCoordinateSystem::GetDefaultValue( sal_Int32 nHandle ) const
378     throw(beans::UnknownPropertyException)
379 {
380     const tPropertyValueMap& rStaticDefaults = *StaticCooSysDefaults::get();
381     tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
382     if( aFound == rStaticDefaults.end() )
383         return uno::Any();
384     return (*aFound).second;
385 }
386 
387 // ____ OPropertySet ____
getInfoHelper()388 ::cppu::IPropertyArrayHelper & SAL_CALL BaseCoordinateSystem::getInfoHelper()
389 {
390     return *StaticCooSysInfoHelper::get();
391 }
392 
393 
394 // ____ XPropertySet ____
getPropertySetInfo()395 Reference< beans::XPropertySetInfo > SAL_CALL BaseCoordinateSystem::getPropertySetInfo()
396     throw (uno::RuntimeException)
397 {
398     return *StaticCooSysInfo::get();
399 }
400 
401 using impl::BaseCoordinateSystem_Base;
402 
403 IMPLEMENT_FORWARD_XINTERFACE2( BaseCoordinateSystem, BaseCoordinateSystem_Base, ::property::OPropertySet )
404 IMPLEMENT_FORWARD_XTYPEPROVIDER2( BaseCoordinateSystem, BaseCoordinateSystem_Base, ::property::OPropertySet )
405 
406 } //  namespace chart
407