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 "UncachedDataSequence.hxx"
28 #include "macros.hxx"
29 #include "PropertyHelper.hxx"
30 #include "CommonFunctors.hxx"
31 #include "ModifyListenerHelper.hxx"
32 
33 #include <algorithm>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <rtl/math.hxx>
36 
37 using namespace ::com::sun::star;
38 
39 using ::com::sun::star::uno::Sequence;
40 using ::com::sun::star::uno::Reference;
41 using ::com::sun::star::uno::Any;
42 using ::rtl::OUString;
43 using ::osl::MutexGuard;
44 
45 // necessary for MS compiler
46 using ::comphelper::OPropertyContainer;
47 using ::chart::impl::UncachedDataSequence_Base;
48 
49 namespace
50 {
51 static const OUString lcl_aServiceName(
52     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.UncachedDataSequence" ));
53 
54 enum
55 {
56 //     PROP_SOURCE_IDENTIFIER,
57     PROP_NUMBERFORMAT_KEY,
58     PROP_PROPOSED_ROLE,
59     PROP_XML_RANGE
60 };
61 }  // anonymous namespace
62 
63 
64 // ____________________
65 namespace chart
66 {
67 
UncachedDataSequence(const Reference<chart2::XInternalDataProvider> & xIntDataProv,const OUString & rRangeRepresentation)68 UncachedDataSequence::UncachedDataSequence(
69     const Reference< chart2::XInternalDataProvider > & xIntDataProv,
70     const OUString & rRangeRepresentation )
71         : OPropertyContainer( GetBroadcastHelper()),
72           UncachedDataSequence_Base( GetMutex()),
73           m_nNumberFormatKey(0),
74           m_xDataProvider( xIntDataProv ),
75           m_aSourceRepresentation( rRangeRepresentation ),
76           m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
77 {
78     registerProperties();
79 }
80 
UncachedDataSequence(const Reference<chart2::XInternalDataProvider> & xIntDataProv,const OUString & rRangeRepresentation,const OUString & rRole)81 UncachedDataSequence::UncachedDataSequence(
82     const Reference< chart2::XInternalDataProvider > & xIntDataProv,
83     const OUString & rRangeRepresentation,
84     const OUString & rRole )
85         : OPropertyContainer( GetBroadcastHelper()),
86           UncachedDataSequence_Base( GetMutex()),
87           m_nNumberFormatKey(0),
88           m_xDataProvider( xIntDataProv ),
89           m_aSourceRepresentation( rRangeRepresentation ),
90           m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
91 {
92     registerProperties();
93     setFastPropertyValue_NoBroadcast( PROP_PROPOSED_ROLE, uno::makeAny( rRole ));
94 }
95 
UncachedDataSequence(const UncachedDataSequence & rSource)96 UncachedDataSequence::UncachedDataSequence( const UncachedDataSequence & rSource )
97         : ::comphelper::OMutexAndBroadcastHelper(),
98           OPropertyContainer( GetBroadcastHelper()),
99           ::comphelper::OPropertyArrayUsageHelper< UncachedDataSequence >(),
100           UncachedDataSequence_Base( GetMutex()),
101           m_nNumberFormatKey( rSource.m_nNumberFormatKey ),
102           m_sRole( rSource.m_sRole ),
103           m_xDataProvider( rSource.m_xDataProvider ),
104           m_aSourceRepresentation( rSource.m_aSourceRepresentation ),
105           m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder())
106 {
107     registerProperties();
108 }
109 
~UncachedDataSequence()110 UncachedDataSequence::~UncachedDataSequence()
111 {}
112 
registerProperties()113 void UncachedDataSequence::registerProperties()
114 {
115     registerProperty( C2U( "NumberFormatKey" ),
116                       PROP_NUMBERFORMAT_KEY,
117                       0,   // PropertyAttributes
118                       & m_nNumberFormatKey,
119                       ::getCppuType( & m_nNumberFormatKey ) );
120 
121     registerProperty( C2U( "Role" ),
122                       PROP_PROPOSED_ROLE,
123                       0,   // PropertyAttributes
124                       & m_sRole,
125                       ::getCppuType( & m_sRole ) );
126 
127     registerProperty( C2U( "CachedXMLRange" ),
128                       PROP_XML_RANGE,
129                       0,   // PropertyAttributes
130                       & m_aXMLRange,
131                       ::getCppuType( & m_aXMLRange ) );
132 }
133 
134 // ================================================================================
135 
getSupportedServiceNames_Static()136 Sequence< OUString > UncachedDataSequence::getSupportedServiceNames_Static()
137 {
138     Sequence< OUString > aServices( 4 );
139     aServices[ 0 ] = lcl_aServiceName;
140     aServices[ 1 ] = C2U( "com.sun.star.chart2.data.DataSequence" );
141     aServices[ 2 ] = C2U( "com.sun.star.chart2.data.NumericalDataSequence" );
142     aServices[ 3 ] = C2U( "com.sun.star.chart2.data.TextualDataSequence" );
143     return aServices;
144 }
145 
IMPLEMENT_FORWARD_XINTERFACE2(UncachedDataSequence,UncachedDataSequence_Base,OPropertyContainer)146 IMPLEMENT_FORWARD_XINTERFACE2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer )
147 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer )
148 
149 // ____ XPropertySet ____
150 Reference< beans::XPropertySetInfo > SAL_CALL UncachedDataSequence::getPropertySetInfo()
151     throw(uno::RuntimeException)
152 {
153     return Reference< beans::XPropertySetInfo >( createPropertySetInfo( getInfoHelper() ) );
154 }
155 
156 // ____ ::comphelper::OPropertySetHelper ____
157 // __________________________________________
getInfoHelper()158 ::cppu::IPropertyArrayHelper& UncachedDataSequence::getInfoHelper()
159 {
160 	return *getArrayHelper();
161 }
162 
163 // ____ ::comphelper::OPropertyArrayHelper ____
164 // ____________________________________________
createArrayHelper() const165 ::cppu::IPropertyArrayHelper* UncachedDataSequence::createArrayHelper() const
166 {
167 	Sequence< beans::Property > aProps;
168     // describes all properties which have been registered in the ctor
169 	describeProperties( aProps );
170 
171 	return new ::cppu::OPropertyArrayHelper( aProps );
172 }
173 
174 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL(UncachedDataSequence,lcl_aServiceName)175 APPHELPER_XSERVICEINFO_IMPL( UncachedDataSequence, lcl_aServiceName )
176 
177 // ================================================================================
178 
179 // ________ XNumericalDataSequence ________
180 Sequence< double > SAL_CALL UncachedDataSequence::getNumericalData()
181     throw (uno::RuntimeException)
182 {
183     Sequence< double > aResult;
184     // /--
185     MutexGuard aGuard( GetMutex() );
186     if( m_xDataProvider.is())
187     {
188         Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation ));
189         aResult.realloc( aValues.getLength());
190         ::std::transform( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
191                           aResult.getArray(), CommonFunctors::AnyToDouble());
192     }
193     return aResult;
194     // \--
195 }
196 
197 // ________ XTextualDataSequence ________
getTextualData()198 Sequence< OUString > SAL_CALL UncachedDataSequence::getTextualData()
199     throw (uno::RuntimeException)
200 {
201     Sequence< OUString > aResult;
202     // /--
203     MutexGuard aGuard( GetMutex() );
204     if( m_xDataProvider.is())
205     {
206         Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation ));
207         aResult.realloc( aValues.getLength());
208         ::std::transform( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
209                           aResult.getArray(), CommonFunctors::AnyToString());
210     }
211     return aResult;
212     // \--
213 }
214 
215 // ________ XDataSequence  ________
getData()216 Sequence< Any > SAL_CALL UncachedDataSequence::getData()
217     throw (uno::RuntimeException)
218 {
219     // /--
220     MutexGuard aGuard( GetMutex() );
221     if( m_xDataProvider.is())
222         return m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation );
223     return Sequence< Any >();
224     // \--
225 }
226 
getSourceRangeRepresentation()227 OUString SAL_CALL UncachedDataSequence::getSourceRangeRepresentation()
228     throw (uno::RuntimeException)
229 {
230     return getName();
231 }
232 
233 
generateLabel(chart2::data::LabelOrigin)234 Sequence< OUString > SAL_CALL UncachedDataSequence::generateLabel( chart2::data::LabelOrigin )
235     throw (uno::RuntimeException)
236 {
237     // auto-generated label is an empty string
238     static const Sequence< OUString > aOneEmptyString( 1 );
239     return aOneEmptyString;
240 }
241 
getNumberFormatKeyByIndex(::sal_Int32)242 ::sal_Int32 SAL_CALL UncachedDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 )
243     throw (lang::IndexOutOfBoundsException,
244            uno::RuntimeException)
245 {
246     return m_nNumberFormatKey;
247 }
248 
249 // ____ XIndexReplace ____
replaceByIndex(::sal_Int32 Index,const uno::Any & Element)250 void SAL_CALL UncachedDataSequence::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element )
251     throw (lang::IllegalArgumentException,
252            lang::IndexOutOfBoundsException,
253            lang::WrappedTargetException,
254            uno::RuntimeException)
255 {
256     // /--
257     MutexGuard aGuard( GetMutex() );
258     Sequence< Any > aData( getData());
259     if( Index < aData.getLength() &&
260         m_xDataProvider.is() )
261     {
262         aData[Index] = Element;
263         m_xDataProvider->setDataByRangeRepresentation( m_aSourceRepresentation, aData );
264         fireModifyEvent();
265     }
266 }
267 
268 // ____ XIndexAccess (base of XIndexReplace) ____
getCount()269 ::sal_Int32 SAL_CALL UncachedDataSequence::getCount()
270     throw (uno::RuntimeException)
271 {
272     OSL_ENSURE( false, "Implement!" );
273     return 0;
274 }
275 
getByIndex(::sal_Int32)276 uno::Any SAL_CALL UncachedDataSequence::getByIndex( ::sal_Int32 )
277     throw (lang::IndexOutOfBoundsException,
278            lang::WrappedTargetException,
279            uno::RuntimeException)
280 {
281     OSL_ENSURE( false, "Implement!" );
282     return uno::Any();
283 }
284 
285 // ____ XElementAccess (base of XIndexAccess) ____
getElementType()286 uno::Type SAL_CALL UncachedDataSequence::getElementType()
287     throw (uno::RuntimeException)
288 {
289     return ::getCppuType( reinterpret_cast< uno::Any * >(0));
290 }
291 
hasElements()292 ::sal_Bool SAL_CALL UncachedDataSequence::hasElements()
293     throw (uno::RuntimeException)
294 {
295     if( ! m_xDataProvider.is())
296         return sal_False;
297     return m_xDataProvider->hasDataByRangeRepresentation( m_aSourceRepresentation );
298 }
299 
300 // ____ XNamed ____
getName()301 ::rtl::OUString SAL_CALL UncachedDataSequence::getName()
302     throw (uno::RuntimeException)
303 {
304     return m_aSourceRepresentation;
305 }
306 
setName(const OUString & aName)307 void SAL_CALL UncachedDataSequence::setName( const OUString& aName )
308     throw (uno::RuntimeException)
309 {
310     m_aSourceRepresentation = aName;
311     fireModifyEvent();
312 }
313 
314 
315 
createClone()316 Reference< util::XCloneable > SAL_CALL UncachedDataSequence::createClone()
317     throw (uno::RuntimeException)
318 {
319     UncachedDataSequence * pNewSeq = new UncachedDataSequence( *this );
320     return Reference< util::XCloneable >( pNewSeq );
321 }
322 
323 
324 // ____ XModifiable ____
isModified()325 ::sal_Bool SAL_CALL UncachedDataSequence::isModified()
326     throw (uno::RuntimeException)
327 {
328     return sal_False;
329 }
330 
setModified(::sal_Bool bModified)331 void SAL_CALL UncachedDataSequence::setModified( ::sal_Bool bModified )
332     throw (beans::PropertyVetoException,
333            uno::RuntimeException)
334 {
335     if( bModified )
336         fireModifyEvent();
337 }
338 
339 // ____ XModifyBroadcaster (base of XModifiable) ____
addModifyListener(const Reference<util::XModifyListener> & aListener)340 void SAL_CALL UncachedDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener )
341     throw (uno::RuntimeException)
342 {
343     try
344     {
345         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
346         xBroadcaster->addModifyListener( aListener );
347     }
348     catch( const uno::Exception & ex )
349     {
350         ASSERT_EXCEPTION( ex );
351     }
352 }
353 
removeModifyListener(const Reference<util::XModifyListener> & aListener)354 void SAL_CALL UncachedDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener )
355     throw (uno::RuntimeException)
356 {
357     try
358     {
359         Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
360         xBroadcaster->removeModifyListener( aListener );
361     }
362     catch( const uno::Exception & ex )
363     {
364         ASSERT_EXCEPTION( ex );
365     }
366 }
367 
fireModifyEvent()368 void UncachedDataSequence::fireModifyEvent()
369 {
370     // @todo: currently never called, as data changes are not yet reported by
371     // the data provider
372     m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
373 }
374 
375 }  // namespace chart
376