Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "CachedDataSequence.hxx"
21 : #include "macros.hxx"
22 : #include "PropertyHelper.hxx"
23 : #include "ContainerHelper.hxx"
24 : #include "CommonFunctors.hxx"
25 : #include "ModifyListenerHelper.hxx"
26 :
27 : #include <comphelper/sequenceashashmap.hxx>
28 :
29 : #include <algorithm>
30 : #include <com/sun/star/beans/PropertyAttribute.hpp>
31 : #include <rtl/math.hxx>
32 :
33 : using namespace ::com::sun::star;
34 : using namespace ::chart::ContainerHelper;
35 :
36 : using ::com::sun::star::uno::Sequence;
37 : using ::com::sun::star::uno::Reference;
38 : using ::com::sun::star::uno::Any;
39 : using ::osl::MutexGuard;
40 :
41 : // necessary for MS compiler
42 : using ::comphelper::OPropertyContainer;
43 : using ::comphelper::OMutexAndBroadcastHelper;
44 : using ::comphelper::OPropertyArrayUsageHelper;
45 : using ::chart::impl::CachedDataSequence_Base;
46 :
47 : namespace
48 : {
49 0 : static const OUString lcl_aServiceName( "com.sun.star.comp.chart.CachedDataSequence" );
50 :
51 : enum
52 : {
53 : // PROP_SOURCE_IDENTIFIER,
54 : PROP_NUMBERFORMAT_KEY,
55 : PROP_PROPOSED_ROLE
56 : };
57 : } // anonymous namespace
58 :
59 : namespace chart
60 : {
61 :
62 0 : CachedDataSequence::CachedDataSequence()
63 0 : : OPropertyContainer( GetBroadcastHelper()),
64 0 : CachedDataSequence_Base( GetMutex()),
65 : m_eCurrentDataType( NUMERICAL ),
66 0 : m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
67 : {
68 0 : registerProperties();
69 0 : }
70 0 : CachedDataSequence::CachedDataSequence( const Reference< uno::XComponentContext > & /*xContext*/ )
71 0 : : OPropertyContainer( GetBroadcastHelper()),
72 0 : CachedDataSequence_Base( GetMutex()),
73 : m_eCurrentDataType( MIXED ),
74 0 : m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder( ))
75 : {
76 0 : registerProperties();
77 0 : }
78 :
79 0 : CachedDataSequence::CachedDataSequence( const OUString & rSingleText )
80 0 : : OPropertyContainer( GetBroadcastHelper()),
81 0 : CachedDataSequence_Base( GetMutex()),
82 : m_eCurrentDataType( TEXTUAL ),
83 0 : m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
84 : {
85 0 : m_aTextualSequence.realloc(1);
86 0 : m_aTextualSequence[0] = rSingleText;
87 0 : registerProperties();
88 0 : }
89 :
90 0 : CachedDataSequence::CachedDataSequence( const CachedDataSequence & rSource )
91 : : OMutexAndBroadcastHelper(),
92 0 : OPropertyContainer( GetBroadcastHelper()),
93 : OPropertyArrayUsageHelper< CachedDataSequence >(),
94 0 : CachedDataSequence_Base( GetMutex()),
95 : m_nNumberFormatKey( rSource.m_nNumberFormatKey ),
96 : m_sRole( rSource.m_sRole ),
97 : m_eCurrentDataType( rSource.m_eCurrentDataType ),
98 0 : m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
99 : {
100 0 : switch( m_eCurrentDataType )
101 : {
102 : case TEXTUAL:
103 0 : m_aTextualSequence = rSource.m_aTextualSequence;
104 0 : break;
105 : case NUMERICAL:
106 0 : m_aNumericalSequence = rSource.m_aNumericalSequence;
107 0 : break;
108 : case MIXED:
109 0 : m_aMixedSequence = rSource.m_aMixedSequence;
110 0 : break;
111 : }
112 :
113 0 : registerProperties();
114 0 : }
115 :
116 0 : CachedDataSequence::~CachedDataSequence()
117 0 : {}
118 :
119 0 : void CachedDataSequence::registerProperties()
120 : {
121 : registerProperty( "NumberFormatKey",
122 : PROP_NUMBERFORMAT_KEY,
123 : 0, // PropertyAttributes
124 : & m_nNumberFormatKey,
125 0 : ::getCppuType( & m_nNumberFormatKey ) );
126 :
127 : registerProperty( "Role",
128 : PROP_PROPOSED_ROLE,
129 : 0, // PropertyAttributes
130 : & m_sRole,
131 0 : ::getCppuType( & m_sRole ) );
132 0 : }
133 :
134 0 : Sequence< double > CachedDataSequence::Impl_getNumericalData() const
135 : {
136 0 : if( m_eCurrentDataType == NUMERICAL )
137 0 : return m_aNumericalSequence;
138 :
139 0 : sal_Int32 nSize = ( m_eCurrentDataType == TEXTUAL )
140 0 : ? m_aTextualSequence.getLength()
141 0 : : m_aMixedSequence.getLength();
142 :
143 0 : Sequence< double > aResult( nSize );
144 0 : double * pResultArray = aResult.getArray();
145 :
146 0 : if( m_eCurrentDataType == TEXTUAL )
147 : {
148 0 : const OUString * pTextArray = m_aTextualSequence.getConstArray();
149 : ::std::transform( pTextArray, pTextArray + nSize,
150 : pResultArray,
151 0 : CommonFunctors::OUStringToDouble() );
152 : }
153 : else
154 : {
155 : OSL_ASSERT( m_eCurrentDataType == MIXED );
156 0 : const Any * pMixedArray = m_aMixedSequence.getConstArray();
157 : ::std::transform( pMixedArray, pMixedArray + nSize,
158 : pResultArray,
159 0 : CommonFunctors::AnyToDouble() );
160 : }
161 0 : return aResult;
162 : }
163 :
164 0 : Sequence< OUString > CachedDataSequence::Impl_getTextualData() const
165 : {
166 0 : if( m_eCurrentDataType == TEXTUAL )
167 0 : return m_aTextualSequence;
168 :
169 0 : sal_Int32 nSize = ( m_eCurrentDataType == NUMERICAL )
170 0 : ? m_aNumericalSequence.getLength()
171 0 : : m_aMixedSequence.getLength();
172 :
173 0 : Sequence< OUString > aResult( nSize );
174 0 : OUString * pResultArray = aResult.getArray();
175 :
176 0 : if( m_eCurrentDataType == NUMERICAL )
177 : {
178 0 : const double * pTextArray = m_aNumericalSequence.getConstArray();
179 : ::std::transform( pTextArray, pTextArray + nSize,
180 : pResultArray,
181 0 : CommonFunctors::DoubleToOUString() );
182 : }
183 : else
184 : {
185 : OSL_ASSERT( m_eCurrentDataType == MIXED );
186 0 : const Any * pMixedArray = m_aMixedSequence.getConstArray();
187 : ::std::transform( pMixedArray, pMixedArray + nSize,
188 : pResultArray,
189 0 : CommonFunctors::AnyToString() );
190 : }
191 :
192 0 : return aResult;
193 : }
194 :
195 0 : Sequence< Any > CachedDataSequence::Impl_getMixedData() const
196 : {
197 0 : if( m_eCurrentDataType == MIXED )
198 0 : return m_aMixedSequence;
199 :
200 0 : sal_Int32 nSize = ( m_eCurrentDataType == NUMERICAL )
201 0 : ? m_aNumericalSequence.getLength()
202 0 : : m_aTextualSequence.getLength();
203 :
204 0 : Sequence< Any > aResult( nSize );
205 0 : Any * pResultArray = aResult.getArray();
206 :
207 0 : if( m_eCurrentDataType == NUMERICAL )
208 : {
209 0 : const double * pTextArray = m_aNumericalSequence.getConstArray();
210 : ::std::transform( pTextArray, pTextArray + nSize,
211 : pResultArray,
212 0 : CommonFunctors::makeAny< double >() );
213 : }
214 : else
215 : {
216 : OSL_ASSERT( m_eCurrentDataType == TEXTUAL );
217 0 : const OUString * pMixedArray = m_aTextualSequence.getConstArray();
218 : ::std::transform( pMixedArray, pMixedArray + nSize,
219 : pResultArray,
220 0 : CommonFunctors::makeAny< OUString >() );
221 : }
222 :
223 0 : return aResult;
224 : }
225 :
226 0 : Sequence< OUString > CachedDataSequence::getSupportedServiceNames_Static()
227 : {
228 0 : Sequence< OUString > aServices( 4 );
229 0 : aServices[ 0 ] = lcl_aServiceName;
230 0 : aServices[ 1 ] = "com.sun.star.chart2.data.DataSequence";
231 0 : aServices[ 2 ] = "com.sun.star.chart2.data.NumericalDataSequence";
232 0 : aServices[ 3 ] = "com.sun.star.chart2.data.TextualDataSequence";
233 0 : return aServices;
234 : }
235 :
236 0 : IMPLEMENT_FORWARD_XINTERFACE2( CachedDataSequence, CachedDataSequence_Base, OPropertyContainer )
237 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( CachedDataSequence, CachedDataSequence_Base, OPropertyContainer )
238 :
239 : // ____ XPropertySet ____
240 0 : Reference< beans::XPropertySetInfo > SAL_CALL CachedDataSequence::getPropertySetInfo()
241 : throw(uno::RuntimeException, std::exception)
242 : {
243 0 : return Reference< beans::XPropertySetInfo >( createPropertySetInfo( getInfoHelper() ) );
244 : }
245 :
246 : // ____ ::comphelper::OPropertySetHelper ____
247 0 : ::cppu::IPropertyArrayHelper& CachedDataSequence::getInfoHelper()
248 : {
249 0 : return *getArrayHelper();
250 : }
251 :
252 : // ____ ::comphelper::OPropertyArrayHelper ____
253 0 : ::cppu::IPropertyArrayHelper* CachedDataSequence::createArrayHelper() const
254 : {
255 0 : Sequence< beans::Property > aProps;
256 : // describes all properties which have been registered in the ctor
257 0 : describeProperties( aProps );
258 :
259 0 : return new ::cppu::OPropertyArrayHelper( aProps );
260 : }
261 :
262 : // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
263 0 : APPHELPER_XSERVICEINFO_IMPL( CachedDataSequence, lcl_aServiceName )
264 :
265 : // ________ XNumericalDataSequence ________
266 0 : Sequence< double > SAL_CALL CachedDataSequence::getNumericalData()
267 : throw (uno::RuntimeException, std::exception)
268 : {
269 0 : MutexGuard aGuard( GetMutex() );
270 :
271 0 : if( m_eCurrentDataType == NUMERICAL )
272 0 : return m_aNumericalSequence;
273 : else
274 0 : return Impl_getNumericalData();
275 : }
276 :
277 : // ________ XTextualDataSequence ________
278 0 : Sequence< OUString > SAL_CALL CachedDataSequence::getTextualData()
279 : throw (uno::RuntimeException, std::exception)
280 : {
281 0 : MutexGuard aGuard( GetMutex() );
282 :
283 0 : if( m_eCurrentDataType == TEXTUAL )
284 0 : return m_aTextualSequence;
285 : else
286 0 : return Impl_getTextualData();
287 : }
288 :
289 : // ________ XDataSequence ________
290 0 : Sequence< Any > SAL_CALL CachedDataSequence::getData()
291 : throw (uno::RuntimeException, std::exception)
292 : {
293 0 : MutexGuard aGuard( GetMutex() );
294 0 : return Impl_getMixedData();
295 : }
296 :
297 0 : OUString SAL_CALL CachedDataSequence::getSourceRangeRepresentation()
298 : throw (uno::RuntimeException, std::exception)
299 : {
300 0 : return m_sRole;
301 : }
302 :
303 0 : Sequence< OUString > SAL_CALL CachedDataSequence::generateLabel( chart2::data::LabelOrigin /*eLabelOrigin*/ )
304 : throw (uno::RuntimeException, std::exception)
305 : {
306 : // return empty label, as we have no range representaions to determine something useful
307 0 : return Sequence< OUString >();
308 : }
309 :
310 0 : ::sal_Int32 SAL_CALL CachedDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 /*nIndex*/ )
311 : throw (lang::IndexOutOfBoundsException,
312 : uno::RuntimeException, std::exception)
313 : {
314 0 : return 0;
315 : }
316 :
317 0 : Reference< util::XCloneable > SAL_CALL CachedDataSequence::createClone()
318 : throw (uno::RuntimeException, std::exception)
319 : {
320 0 : CachedDataSequence * pNewSeq = new CachedDataSequence( *this );
321 :
322 0 : return Reference< util::XCloneable >( pNewSeq );
323 : }
324 :
325 0 : void SAL_CALL CachedDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener )
326 : throw (uno::RuntimeException, std::exception)
327 : {
328 : try
329 : {
330 0 : Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
331 0 : xBroadcaster->addModifyListener( aListener );
332 : }
333 0 : catch( const uno::Exception & ex )
334 : {
335 : ASSERT_EXCEPTION( ex );
336 : }
337 0 : }
338 :
339 0 : void SAL_CALL CachedDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener )
340 : throw (uno::RuntimeException, std::exception)
341 : {
342 : try
343 : {
344 0 : Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
345 0 : xBroadcaster->removeModifyListener( aListener );
346 : }
347 0 : catch( const uno::Exception & ex )
348 : {
349 : ASSERT_EXCEPTION( ex );
350 : }
351 0 : }
352 :
353 : // lang::XInitialization:
354 0 : void SAL_CALL CachedDataSequence::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception, std::exception)
355 : {
356 0 : ::comphelper::SequenceAsHashMap aMap(_aArguments);
357 0 : m_aNumericalSequence = aMap.getUnpackedValueOrDefault( "DataSequence" ,m_aNumericalSequence);
358 0 : if ( m_aNumericalSequence.getLength() )
359 0 : m_eCurrentDataType = NUMERICAL;
360 : else
361 : {
362 0 : m_aTextualSequence = aMap.getUnpackedValueOrDefault( "DataSequence" ,m_aTextualSequence);
363 0 : if ( m_aTextualSequence.getLength() )
364 0 : m_eCurrentDataType = TEXTUAL;
365 : else
366 : {
367 0 : m_aMixedSequence = aMap.getUnpackedValueOrDefault( "DataSequence" ,m_aMixedSequence);
368 0 : if ( m_aMixedSequence.getLength() )
369 0 : m_eCurrentDataType = MIXED;
370 : }
371 0 : }
372 0 : }
373 0 : } // namespace chart
374 :
375 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|