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 "ChartType.hxx"
27 #include "PropertyHelper.hxx"
28 #include "CommonFunctors.hxx"
29 #include "macros.hxx"
30 #include "CartesianCoordinateSystem.hxx"
31 #include "AxisHelper.hxx"
32 #include "CloneHelper.hxx"
33 #include "AxisIndexDefines.hxx"
34 #include "ContainerHelper.hxx"
35 #include <com/sun/star/chart2/AxisType.hpp>
36 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 
38 using namespace ::com::sun::star;
39 
40 using ::rtl::OUString;
41 using ::com::sun::star::beans::Property;
42 using ::com::sun::star::uno::Sequence;
43 using ::com::sun::star::uno::Reference;
44 using ::com::sun::star::uno::Any;
45 using ::osl::MutexGuard;
46 
47 namespace chart
48 {
49 
ChartType(const Reference<uno::XComponentContext> & xContext)50 ChartType::ChartType(
51     const Reference< uno::XComponentContext > & xContext ) :
52         ::property::OPropertySet( m_aMutex ),
53         m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()),
54         m_xContext( xContext ),
55         m_bNotifyChanges( true )
56 {}
57 
ChartType(const ChartType & rOther)58 ChartType::ChartType( const ChartType & rOther ) :
59         MutexContainer(),
60         impl::ChartType_Base(),
61         ::property::OPropertySet( rOther, m_aMutex ),
62     m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()),
63     m_xContext( rOther.m_xContext ),
64     m_bNotifyChanges( true )
65 {
66     CloneHelper::CloneRefVector< Reference< chart2::XDataSeries > >( rOther.m_aDataSeries, m_aDataSeries );
67     ModifyListenerHelper::addListenerToAllElements( m_aDataSeries, m_xModifyEventForwarder );
68 }
69 
~ChartType()70 ChartType::~ChartType()
71 {
72     ModifyListenerHelper::removeListenerFromAllElements( m_aDataSeries, m_xModifyEventForwarder );
73     m_aDataSeries.clear();
74 }
75 
GetComponentContext() const76 Reference< uno::XComponentContext > ChartType::GetComponentContext() const
77 {
78     return m_xContext;
79 }
80 
81 // ____ XChartType ____
82 Reference< chart2::XCoordinateSystem > SAL_CALL
createCoordinateSystem(::sal_Int32 DimensionCount)83     ChartType::createCoordinateSystem( ::sal_Int32 DimensionCount )
84     throw (lang::IllegalArgumentException,
85            uno::RuntimeException)
86 {
87     Reference< chart2::XCoordinateSystem > xResult(
88         new CartesianCoordinateSystem(
89             GetComponentContext(), DimensionCount, /* bSwapXAndYAxis */ sal_False ));
90 
91     for( sal_Int32 i=0; i<DimensionCount; ++i )
92     {
93         Reference< chart2::XAxis > xAxis( xResult->getAxisByDimension( i, MAIN_AXIS_INDEX ) );
94         if( !xAxis.is() )
95         {
96             OSL_ENSURE(false,"a created coordinate system should have an axis for each dimension");
97             continue;
98         }
99 
100         chart2::ScaleData aScaleData = xAxis->getScaleData();
101         aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
102         aScaleData.Scaling = AxisHelper::createLinearScaling();
103 
104         switch( i )
105         {
106             case 0: aScaleData.AxisType = chart2::AxisType::CATEGORY; break;
107             case 2: aScaleData.AxisType = chart2::AxisType::SERIES; break;
108             default: aScaleData.AxisType = chart2::AxisType::REALNUMBER; break;
109         }
110 
111         xAxis->setScaleData( aScaleData );
112     }
113 
114     return xResult;
115 }
116 
getSupportedMandatoryRoles()117 Sequence< OUString > SAL_CALL ChartType::getSupportedMandatoryRoles()
118     throw (uno::RuntimeException)
119 {
120     static Sequence< OUString > aDefaultSeq;
121 
122     if( aDefaultSeq.getLength() == 0 )
123     {
124         aDefaultSeq.realloc( 2 );
125         aDefaultSeq[0] = C2U( "label" );
126         aDefaultSeq[1] = C2U( "values-y" );
127     }
128 
129     return aDefaultSeq;
130 }
131 
getSupportedOptionalRoles()132 Sequence< OUString > SAL_CALL ChartType::getSupportedOptionalRoles()
133     throw (uno::RuntimeException)
134 {
135     static Sequence< OUString > aDefaultOptRolesSeq;
136 
137 //     if( aDefaultOptRolesSeq.getLength() == 0 )
138 //     {
139 //         aDefaultOptRolesSeq.realloc( 1 );
140 //         aDefaultOptRolesSeq[0] = C2U( "error-bars-y" );
141 //     }
142 
143     return aDefaultOptRolesSeq;
144 }
145 
getRoleOfSequenceForSeriesLabel()146 OUString SAL_CALL ChartType::getRoleOfSequenceForSeriesLabel()
147     throw (uno::RuntimeException)
148 {
149     return C2U( "values-y" );
150 }
151 
impl_addDataSeriesWithoutNotification(const Reference<chart2::XDataSeries> & xDataSeries)152 void ChartType::impl_addDataSeriesWithoutNotification(
153         const Reference< chart2::XDataSeries >& xDataSeries )
154 {
155     if( ::std::find( m_aDataSeries.begin(), m_aDataSeries.end(), xDataSeries )
156         != m_aDataSeries.end())
157         throw lang::IllegalArgumentException();
158 
159     m_aDataSeries.push_back( xDataSeries );
160     ModifyListenerHelper::addListener( xDataSeries, m_xModifyEventForwarder );
161 }
162 
163 // ____ XDataSeriesContainer ____
addDataSeries(const Reference<chart2::XDataSeries> & xDataSeries)164 void SAL_CALL ChartType::addDataSeries( const Reference< chart2::XDataSeries >& xDataSeries )
165     throw (lang::IllegalArgumentException,
166            uno::RuntimeException)
167 {
168     impl_addDataSeriesWithoutNotification( xDataSeries );
169     fireModifyEvent();
170 }
171 
removeDataSeries(const Reference<chart2::XDataSeries> & xDataSeries)172 void SAL_CALL ChartType::removeDataSeries( const Reference< chart2::XDataSeries >& xDataSeries )
173     throw (container::NoSuchElementException,
174            uno::RuntimeException)
175 {
176     if( !xDataSeries.is())
177         throw container::NoSuchElementException();
178 
179     tDataSeriesContainerType::iterator aIt(
180             ::std::find( m_aDataSeries.begin(), m_aDataSeries.end(), xDataSeries ) );
181 
182     if( aIt == m_aDataSeries.end())
183         throw container::NoSuchElementException(
184             C2U( "The given series is no element of this charttype" ),
185             static_cast< uno::XWeak * >( this ));
186 
187     ModifyListenerHelper::removeListener( xDataSeries, m_xModifyEventForwarder );
188     m_aDataSeries.erase( aIt );
189     fireModifyEvent();
190 }
191 
getDataSeries()192 Sequence< Reference< chart2::XDataSeries > > SAL_CALL ChartType::getDataSeries()
193     throw (uno::RuntimeException)
194 {
195     return ContainerHelper::ContainerToSequence( m_aDataSeries );
196 }
197 
setDataSeries(const Sequence<Reference<chart2::XDataSeries>> & aDataSeries)198 void SAL_CALL ChartType::setDataSeries( const Sequence< Reference< chart2::XDataSeries > >& aDataSeries )
199     throw (lang::IllegalArgumentException,
200            uno::RuntimeException)
201 {
202     m_bNotifyChanges = false;
203     try
204     {
205         Sequence< Reference< chart2::XDataSeries > > aOldSeries( this->getDataSeries() );
206         for( sal_Int32 nN=0; nN<aOldSeries.getLength(); ++nN )
207             ModifyListenerHelper::removeListener( aOldSeries[nN], m_xModifyEventForwarder );
208         m_aDataSeries.clear();
209 
210         for( sal_Int32 i=0; i<aDataSeries.getLength(); ++i )
211             impl_addDataSeriesWithoutNotification( aDataSeries[i] );
212     }
213     catch( ... )
214     {
215         m_bNotifyChanges = true;
216         throw;
217     }
218     m_bNotifyChanges = true;
219     fireModifyEvent();
220 }
221 
222 // ____ OPropertySet ____
GetDefaultValue(sal_Int32) const223 uno::Any ChartType::GetDefaultValue( sal_Int32 /* nHandle */ ) const
224     throw(beans::UnknownPropertyException)
225 {
226     return uno::Any();
227 }
228 
229 namespace
230 {
231 
232 struct StaticChartTypeInfoHelper_Initializer
233 {
operator ()chart::__anon1268f7890111::StaticChartTypeInfoHelper_Initializer234     ::cppu::OPropertyArrayHelper* operator()()
235     {
236         // using assignment for broken gcc 3.3
237         static ::cppu::OPropertyArrayHelper aPropHelper = ::cppu::OPropertyArrayHelper(
238             Sequence< beans::Property >() );
239         return &aPropHelper;
240     }
241 };
242 
243 struct StaticChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticChartTypeInfoHelper_Initializer >
244 {
245 };
246 
247 struct StaticChartTypeInfo_Initializer
248 {
operator ()chart::__anon1268f7890111::StaticChartTypeInfo_Initializer249     uno::Reference< beans::XPropertySetInfo >* operator()()
250     {
251         static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
252             ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticChartTypeInfoHelper::get() ) );
253         return &xPropertySetInfo;
254     }
255 };
256 
257 struct StaticChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticChartTypeInfo_Initializer >
258 {
259 };
260 
261 }
262 
263 // ____ OPropertySet ____
getInfoHelper()264 ::cppu::IPropertyArrayHelper & SAL_CALL ChartType::getInfoHelper()
265 {
266     return *StaticChartTypeInfoHelper::get();
267 }
268 
269 // ____ XPropertySet ____
getPropertySetInfo()270 uno::Reference< beans::XPropertySetInfo > SAL_CALL ChartType::getPropertySetInfo()
271     throw (uno::RuntimeException)
272 {
273     return *StaticChartTypeInfo::get();
274 }
275 
276 // ____ XModifyBroadcaster ____
addModifyListener(const uno::Reference<util::XModifyListener> & aListener)277 void SAL_CALL ChartType::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
278     throw (uno::RuntimeException)
279 {
280     try
281     {
282         uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
283         xBroadcaster->addModifyListener( aListener );
284     }
285     catch( const uno::Exception & ex )
286     {
287         ASSERT_EXCEPTION( ex );
288     }
289 }
290 
removeModifyListener(const uno::Reference<util::XModifyListener> & aListener)291 void SAL_CALL ChartType::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
292     throw (uno::RuntimeException)
293 {
294     try
295     {
296         uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
297         xBroadcaster->removeModifyListener( aListener );
298     }
299     catch( const uno::Exception & ex )
300     {
301         ASSERT_EXCEPTION( ex );
302     }
303 }
304 
305 // ____ XModifyListener ____
modified(const lang::EventObject & aEvent)306 void SAL_CALL ChartType::modified( const lang::EventObject& aEvent )
307     throw (uno::RuntimeException)
308 {
309     m_xModifyEventForwarder->modified( aEvent );
310 }
311 
312 // ____ XEventListener (base of XModifyListener) ____
disposing(const lang::EventObject &)313 void SAL_CALL ChartType::disposing( const lang::EventObject& /* Source */ )
314     throw (uno::RuntimeException)
315 {
316     // nothing
317 }
318 
319 // ____ OPropertySet ____
firePropertyChangeEvent()320 void ChartType::firePropertyChangeEvent()
321 {
322     fireModifyEvent();
323 }
324 
fireModifyEvent()325 void ChartType::fireModifyEvent()
326 {
327     if( m_bNotifyChanges )
328         m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
329 }
330 
331 // ================================================================================
332 
333 using impl::ChartType_Base;
334 
335 IMPLEMENT_FORWARD_XINTERFACE2( ChartType, ChartType_Base, ::property::OPropertySet )
336 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ChartType, ChartType_Base, ::property::OPropertySet )
337 
338 } //  namespace chart
339