xref: /trunk/main/chart2/source/tools/CachedDataSequence.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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_charttools.hxx"
26 
27 #include "CachedDataSequence.hxx"
28 #include "macros.hxx"
29 #include "PropertyHelper.hxx"
30 #include "ContainerHelper.hxx"
31 #include "CommonFunctors.hxx"
32 #include "ModifyListenerHelper.hxx"
33 
34 #include <comphelper/sequenceashashmap.hxx>
35 
36 #include <algorithm>
37 #include <com/sun/star/beans/PropertyAttribute.hpp>
38 #include <rtl/math.hxx>
39 
40 using namespace ::com::sun::star;
41 using namespace ::chart::ContainerHelper;
42 
43 using ::com::sun::star::uno::Sequence;
44 using ::com::sun::star::uno::Reference;
45 using ::com::sun::star::uno::Any;
46 using ::rtl::OUString;
47 using ::osl::MutexGuard;
48 
49 // necessary for MS compiler
50 using ::comphelper::OPropertyContainer;
51 using ::comphelper::OMutexAndBroadcastHelper;
52 using ::comphelper::OPropertyArrayUsageHelper;
53 using ::chart::impl::CachedDataSequence_Base;
54 
55 namespace
56 {
57 static const OUString lcl_aServiceName(
58     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.CachedDataSequence" ));
59 
60 enum
61 {
62 //     PROP_SOURCE_IDENTIFIER,
63     PROP_NUMBERFORMAT_KEY,
64     PROP_PROPOSED_ROLE
65 };
66 }  // anonymous namespace
67 
68 
69 // ____________________
70 namespace chart
71 {
72 
CachedDataSequence()73 CachedDataSequence::CachedDataSequence()
74         : OPropertyContainer( GetBroadcastHelper()),
75           CachedDataSequence_Base( GetMutex()),
76           m_eCurrentDataType( NUMERICAL ),
77           m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
78 {
79     registerProperties();
80 }
CachedDataSequence(const Reference<uno::XComponentContext> &)81 CachedDataSequence::CachedDataSequence( const Reference< uno::XComponentContext > & /*xContext*/ )
82         : OPropertyContainer( GetBroadcastHelper()),
83           CachedDataSequence_Base( GetMutex()),
84           m_eCurrentDataType( MIXED ),
85           m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder( ))
86 {
87     registerProperties();
88 }
89 
CachedDataSequence(const OUString & rSingleText)90 CachedDataSequence::CachedDataSequence( const OUString & rSingleText )
91         : OPropertyContainer( GetBroadcastHelper()),
92           CachedDataSequence_Base( GetMutex()),
93           m_eCurrentDataType( TEXTUAL ),
94           m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
95 {
96     m_aTextualSequence.realloc(1);
97     m_aTextualSequence[0] = rSingleText;
98     registerProperties();
99 }
100 
CachedDataSequence(const CachedDataSequence & rSource)101 CachedDataSequence::CachedDataSequence( const CachedDataSequence & rSource )
102         : OMutexAndBroadcastHelper(),
103           OPropertyContainer( GetBroadcastHelper()),
104           OPropertyArrayUsageHelper< CachedDataSequence >(),
105           CachedDataSequence_Base( GetMutex()),
106           m_nNumberFormatKey( rSource.m_nNumberFormatKey ),
107           m_sRole( rSource.m_sRole ),
108           m_eCurrentDataType( rSource.m_eCurrentDataType ),
109           m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
110 {
111     switch( m_eCurrentDataType )
112     {
113         case TEXTUAL:
114             m_aTextualSequence = rSource.m_aTextualSequence;
115             break;
116         case NUMERICAL:
117             m_aNumericalSequence = rSource.m_aNumericalSequence;
118             break;
119         case MIXED:
120             m_aMixedSequence = rSource.m_aMixedSequence;
121             break;
122     }
123 
124     registerProperties();
125 }
126 
~CachedDataSequence()127 CachedDataSequence::~CachedDataSequence()
128 {}
129 
registerProperties()130 void CachedDataSequence::registerProperties()
131 {
132     registerProperty( C2U( "NumberFormatKey" ),
133                       PROP_NUMBERFORMAT_KEY,
134                       0,   // PropertyAttributes
135                       & m_nNumberFormatKey,
136                       ::getCppuType( & m_nNumberFormatKey ) );
137 
138     registerProperty( C2U( "Role" ),
139                       PROP_PROPOSED_ROLE,
140                       0,   // PropertyAttributes
141                       & m_sRole,
142                       ::getCppuType( & m_sRole ) );
143 }
144 
Impl_getNumericalData() const145 Sequence< double > CachedDataSequence::Impl_getNumericalData() const
146 {
147     if( m_eCurrentDataType == NUMERICAL )
148         return m_aNumericalSequence;
149 
150     sal_Int32 nSize = ( m_eCurrentDataType == TEXTUAL )
151         ? m_aTextualSequence.getLength()
152         : m_aMixedSequence.getLength();
153 
154     Sequence< double > aResult( nSize );
155     double * pResultArray = aResult.getArray();
156 
157     if( m_eCurrentDataType == TEXTUAL )
158     {
159         const OUString * pTextArray = m_aTextualSequence.getConstArray();
160         ::std::transform( pTextArray, pTextArray + nSize,
161                           pResultArray,
162                           CommonFunctors::OUStringToDouble() );
163     }
164     else
165     {
166         OSL_ASSERT( m_eCurrentDataType == MIXED );
167         const Any * pMixedArray = m_aMixedSequence.getConstArray();
168         ::std::transform( pMixedArray, pMixedArray + nSize,
169                           pResultArray,
170                           CommonFunctors::AnyToDouble() );
171     }
172     return aResult;
173 }
174 
Impl_getTextualData() const175 Sequence< OUString > CachedDataSequence::Impl_getTextualData() const
176 {
177     if( m_eCurrentDataType == TEXTUAL )
178         return m_aTextualSequence;
179 
180     sal_Int32 nSize = ( m_eCurrentDataType == NUMERICAL )
181         ? m_aNumericalSequence.getLength()
182         : m_aMixedSequence.getLength();
183 
184     Sequence< OUString > aResult( nSize );
185     OUString * pResultArray = aResult.getArray();
186 
187     if( m_eCurrentDataType == NUMERICAL )
188     {
189         const double * pTextArray = m_aNumericalSequence.getConstArray();
190         ::std::transform( pTextArray, pTextArray + nSize,
191                           pResultArray,
192                           CommonFunctors::DoubleToOUString() );
193     }
194     else
195     {
196         OSL_ASSERT( m_eCurrentDataType == MIXED );
197         const Any * pMixedArray = m_aMixedSequence.getConstArray();
198         ::std::transform( pMixedArray, pMixedArray + nSize,
199                           pResultArray,
200                           CommonFunctors::AnyToString() );
201     }
202 
203     return aResult;
204 }
205 
Impl_getMixedData() const206 Sequence< Any > CachedDataSequence::Impl_getMixedData() const
207 {
208     if( m_eCurrentDataType == MIXED )
209         return m_aMixedSequence;
210 
211     sal_Int32 nSize = ( m_eCurrentDataType == NUMERICAL )
212         ? m_aNumericalSequence.getLength()
213         : m_aTextualSequence.getLength();
214 
215     Sequence< Any > aResult( nSize );
216     Any * pResultArray = aResult.getArray();
217 
218     if( m_eCurrentDataType == NUMERICAL )
219     {
220         const double * pTextArray = m_aNumericalSequence.getConstArray();
221         ::std::transform( pTextArray, pTextArray + nSize,
222                           pResultArray,
223                           CommonFunctors::makeAny< double >() );
224     }
225     else
226     {
227         OSL_ASSERT( m_eCurrentDataType == TEXTUAL );
228         const OUString * pMixedArray = m_aTextualSequence.getConstArray();
229         ::std::transform( pMixedArray, pMixedArray + nSize,
230                           pResultArray,
231                           CommonFunctors::makeAny< OUString >() );
232     }
233 
234     return aResult;
235 }
236 
237 // ================================================================================
238 
getSupportedServiceNames_Static()239 Sequence< OUString > CachedDataSequence::getSupportedServiceNames_Static()
240 {
241     Sequence< OUString > aServices( 4 );
242     aServices[ 0 ] = lcl_aServiceName;
243     aServices[ 1 ] = C2U( "com.sun.star.chart2.data.DataSequence" );
244     aServices[ 2 ] = C2U( "com.sun.star.chart2.data.NumericalDataSequence" );
245     aServices[ 3 ] = C2U( "com.sun.star.chart2.data.TextualDataSequence" );
246     return aServices;
247 }
248 
IMPLEMENT_FORWARD_XINTERFACE2(CachedDataSequence,CachedDataSequence_Base,OPropertyContainer)249 IMPLEMENT_FORWARD_XINTERFACE2( CachedDataSequence, CachedDataSequence_Base, OPropertyContainer )
250 IMPLEMENT_FORWARD_XTYPEPROVIDER2( CachedDataSequence, CachedDataSequence_Base, OPropertyContainer )
251 
252 // ____ XPropertySet ____
253 Reference< beans::XPropertySetInfo > SAL_CALL CachedDataSequence::getPropertySetInfo()
254 {
255     return Reference< beans::XPropertySetInfo >( createPropertySetInfo( getInfoHelper() ) );
256 }
257 
258 // ____ ::comphelper::OPropertySetHelper ____
259 // __________________________________________
getInfoHelper()260 ::cppu::IPropertyArrayHelper& CachedDataSequence::getInfoHelper()
261 {
262     return *getArrayHelper();
263 }
264 
265 // ____ ::comphelper::OPropertyArrayHelper ____
266 // ____________________________________________
createArrayHelper() const267 ::cppu::IPropertyArrayHelper* CachedDataSequence::createArrayHelper() const
268 {
269     Sequence< beans::Property > aProps;
270     // describes all properties which have been registered in the ctor
271     describeProperties( aProps );
272 
273     return new ::cppu::OPropertyArrayHelper( aProps );
274 }
275 
276 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL(CachedDataSequence,lcl_aServiceName)277 APPHELPER_XSERVICEINFO_IMPL( CachedDataSequence, lcl_aServiceName )
278 
279 // ================================================================================
280 
281 // ________ XNumericalDataSequence ________
282 Sequence< double > SAL_CALL CachedDataSequence::getNumericalData()
283 {
284     // /--
285     MutexGuard aGuard( GetMutex() );
286 
287     if( m_eCurrentDataType == NUMERICAL )
288         return m_aNumericalSequence;
289     else
290         return Impl_getNumericalData();
291     // \--
292 }
293 
294 // ________ XTextualDataSequence ________
getTextualData()295 Sequence< OUString > SAL_CALL CachedDataSequence::getTextualData()
296 {
297     // /--
298     MutexGuard aGuard( GetMutex() );
299 
300     if( m_eCurrentDataType == TEXTUAL )
301         return m_aTextualSequence;
302     else
303         return Impl_getTextualData();
304     // \--
305 }
306 
307 // void SAL_CALL CachedDataSequence::setTextualData( const Sequence< OUString >& aData )
308 //     throw (uno::RuntimeException)
309 // {
310 //     // /--
311 //     MutexGuard aGuard( GetMutex() );
312 //     Impl_setTextualData( aData );
313 //     // \--
314 // }
315 
316 // ________ XDataSequence  ________
getData()317 Sequence< Any > SAL_CALL CachedDataSequence::getData()
318 {
319     // /--
320     MutexGuard aGuard( GetMutex() );
321     return Impl_getMixedData();
322     // \--
323 }
324 
getSourceRangeRepresentation()325 OUString SAL_CALL CachedDataSequence::getSourceRangeRepresentation()
326 {
327     return m_sRole;
328 }
329 
generateLabel(chart2::data::LabelOrigin)330 Sequence< OUString > SAL_CALL CachedDataSequence::generateLabel( chart2::data::LabelOrigin  /*eLabelOrigin*/ )
331 {
332     // return empty label, as we have no range representaions to determine something useful
333     return Sequence< OUString >();
334 }
335 
getNumberFormatKeyByIndex(::sal_Int32)336 ::sal_Int32 SAL_CALL CachedDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 /*nIndex*/ )
337 {
338     return 0;
339 }
340 
createClone()341 Reference< util::XCloneable > SAL_CALL CachedDataSequence::createClone()
342 {
343     CachedDataSequence * pNewSeq = new CachedDataSequence( *this );
344 
345     return Reference< util::XCloneable >( pNewSeq );
346 }
347 
addModifyListener(const Reference<util::XModifyListener> & aListener)348 void SAL_CALL CachedDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener )
349 {
350     try
351     {
352         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
353         xBroadcaster->addModifyListener( aListener );
354     }
355     catch( const uno::Exception & ex )
356     {
357         ASSERT_EXCEPTION( ex );
358     }
359 }
360 
removeModifyListener(const Reference<util::XModifyListener> & aListener)361 void SAL_CALL CachedDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener )
362 {
363     try
364     {
365         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
366         xBroadcaster->removeModifyListener( aListener );
367     }
368     catch( const uno::Exception & ex )
369     {
370         ASSERT_EXCEPTION( ex );
371     }
372 }
373 
374 // lang::XInitialization:
initialize(const uno::Sequence<uno::Any> & _aArguments)375 void SAL_CALL CachedDataSequence::initialize(const uno::Sequence< uno::Any > & _aArguments)
376 {
377     ::comphelper::SequenceAsHashMap aMap(_aArguments);
378     m_aNumericalSequence = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSequence")),m_aNumericalSequence);
379     if ( m_aNumericalSequence.getLength() )
380         m_eCurrentDataType = NUMERICAL;
381     else
382     {
383         m_aTextualSequence = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSequence")),m_aTextualSequence);
384         if ( m_aTextualSequence.getLength() )
385             m_eCurrentDataType = TEXTUAL;
386         else
387         {
388             m_aMixedSequence = aMap.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSequence")),m_aMixedSequence);
389             if ( m_aMixedSequence.getLength() )
390                 m_eCurrentDataType = MIXED;
391         }
392     }
393 }
394 }  // namespace chart
395