Branch data 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 "ChartDataWrapper.hxx"
21 : : #include "macros.hxx"
22 : : #include "DiagramHelper.hxx"
23 : : #include "DataSourceHelper.hxx"
24 : : #include "servicenames_charttypes.hxx"
25 : : #include "ContainerHelper.hxx"
26 : : #include "CommonFunctors.hxx"
27 : : #include "ChartModelHelper.hxx"
28 : : #include "DataSeriesHelper.hxx"
29 : : #include "ControllerLockGuard.hxx"
30 : : #include "Chart2ModelContact.hxx"
31 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
32 : : #include <com/sun/star/chart2/XTitled.hpp>
33 : : #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
34 : : #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
35 : : #include <com/sun/star/chart2/data/XDataSource.hpp>
36 : : #include <com/sun/star/chart2/XDataSeries.hpp>
37 : : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
38 : : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
39 : : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
40 : : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
41 : : #include <com/sun/star/chart/ChartDataRowSource.hpp>
42 : : #include <com/sun/star/chart/XChartDocument.hpp>
43 : :
44 : : #include "CharacterProperties.hxx"
45 : : #include "LineProperties.hxx"
46 : : #include "FillProperties.hxx"
47 : :
48 : : #include <map>
49 : : #include <algorithm>
50 : : #include <rtl/math.hxx>
51 : :
52 : : using namespace ::com::sun::star;
53 : : using ::com::sun::star::uno::Reference;
54 : : using ::com::sun::star::uno::Sequence;
55 : : using ::rtl::OUString;
56 : : using ::osl::MutexGuard;
57 : : using ::com::sun::star::chart2::XAnyDescriptionAccess;
58 : : using ::com::sun::star::chart::XComplexDescriptionAccess;
59 : : using ::com::sun::star::chart::XChartData;
60 : : using ::com::sun::star::chart::XChartDataArray;
61 : : using ::com::sun::star::chart::XDateCategories;
62 : :
63 : : namespace
64 : : {
65 : 16 : static const ::rtl::OUString lcl_aServiceName(
66 : : RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" ));
67 : :
68 : 10 : uno::Sequence< uno::Sequence< double > > lcl_getNANInsteadDBL_MIN( const uno::Sequence< uno::Sequence< double > >& rData )
69 : : {
70 : 10 : uno::Sequence< uno::Sequence< double > > aRet;
71 : 10 : const sal_Int32 nOuterSize = rData.getLength();
72 [ + - ]: 10 : aRet.realloc( nOuterSize );
73 [ + + ]: 50 : for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
74 : : {
75 : 40 : sal_Int32 nInnerSize = rData[nOuter].getLength();
76 [ + - ][ + - ]: 40 : aRet[nOuter].realloc( nInnerSize );
77 [ + + ]: 160 : for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
78 : : {
79 [ + - ][ + - ]: 120 : aRet[nOuter][nInner] = rData[nOuter][nInner];
80 [ + - ][ + - ]: 120 : double& rValue = aRet[nOuter][nInner];
81 [ - + ]: 120 : if( rValue == DBL_MIN )
82 : 0 : ::rtl::math::setNan( &rValue );
83 : : }
84 : : }
85 : 10 : return aRet;
86 : : }
87 : :
88 : 12 : uno::Sequence< uno::Sequence< double > > lcl_getDBL_MINInsteadNAN( const uno::Sequence< uno::Sequence< double > >& rData )
89 : : {
90 : 12 : uno::Sequence< uno::Sequence< double > > aRet;
91 : 12 : const sal_Int32 nOuterSize = rData.getLength();
92 [ + - ]: 12 : aRet.realloc( nOuterSize );
93 [ + + ]: 60 : for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
94 : : {
95 : 48 : sal_Int32 nInnerSize = rData[nOuter].getLength();
96 [ + - ][ + - ]: 48 : aRet[nOuter].realloc( nInnerSize );
97 [ + + ]: 192 : for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
98 : : {
99 [ + - ][ + - ]: 144 : aRet[nOuter][nInner] = rData[nOuter][nInner];
100 [ + - ][ + - ]: 144 : double& rValue = aRet[nOuter][nInner];
101 [ - + ]: 144 : if( ::rtl::math::isNan( rValue ) )
102 : 0 : rValue = DBL_MIN;
103 : : }
104 : : }
105 : 12 : return aRet;
106 : : }
107 : :
108 : : } // anonymous namespace
109 : :
110 : : // --------------------------------------------------------------------------------
111 : :
112 : : namespace chart
113 : : {
114 : : namespace wrapper
115 : : {
116 : :
117 : : //--------------------------------------------------------------------------------------
118 : :
119 : : struct lcl_Operator
120 : : {
121 : 14 : lcl_Operator()
122 : 14 : {
123 : 14 : }
124 : 14 : virtual ~lcl_Operator()
125 : 14 : {
126 [ - + ]: 14 : }
127 : : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) = 0;
128 : :
129 : 0 : virtual bool setsCategories( bool /*bDataInColumns*/ )
130 : : {
131 : 0 : return false;
132 : : }
133 : : };
134 : :
135 : : //--------------------------------------------------------------------------
136 : :
137 [ # # ]: 0 : struct lcl_AllOperator : public lcl_Operator
138 : : {
139 : 0 : lcl_AllOperator( const Reference< XChartData >& xDataToApply )
140 : : : lcl_Operator()
141 : 0 : , m_xDataToApply( xDataToApply )
142 : : {
143 : 0 : }
144 : :
145 : 0 : virtual bool setsCategories( bool /*bDataInColumns*/ )
146 : : {
147 : 0 : return true;
148 : : }
149 : :
150 : 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
151 : : {
152 [ # # ]: 0 : if( !xDataAccess.is() )
153 : 0 : return;
154 : :
155 [ # # ]: 0 : Reference< XAnyDescriptionAccess > xNewAny( m_xDataToApply, uno::UNO_QUERY );
156 [ # # ]: 0 : Reference< XComplexDescriptionAccess > xNewComplex( m_xDataToApply, uno::UNO_QUERY );
157 [ # # ]: 0 : if( xNewAny.is() )
158 : : {
159 [ # # ][ # # ]: 0 : xDataAccess->setData( xNewAny->getData() );
[ # # ][ # # ]
[ # # ]
160 [ # # ][ # # ]: 0 : xDataAccess->setComplexRowDescriptions( xNewAny->getComplexRowDescriptions() );
[ # # ][ # # ]
[ # # ]
161 [ # # ][ # # ]: 0 : xDataAccess->setComplexColumnDescriptions( xNewAny->getComplexColumnDescriptions() );
[ # # ][ # # ]
[ # # ]
162 : : }
163 [ # # ]: 0 : else if( xNewComplex.is() )
164 : : {
165 [ # # ][ # # ]: 0 : xDataAccess->setData( xNewComplex->getData() );
[ # # ][ # # ]
[ # # ]
166 [ # # ][ # # ]: 0 : xDataAccess->setComplexRowDescriptions( xNewComplex->getComplexRowDescriptions() );
[ # # ][ # # ]
[ # # ]
167 [ # # ][ # # ]: 0 : xDataAccess->setComplexColumnDescriptions( xNewComplex->getComplexColumnDescriptions() );
[ # # ][ # # ]
[ # # ]
168 : : }
169 : : else
170 : : {
171 [ # # ]: 0 : Reference< XChartDataArray > xNew( m_xDataToApply, uno::UNO_QUERY );
172 [ # # ]: 0 : if( xNew.is() )
173 : : {
174 [ # # ][ # # ]: 0 : xDataAccess->setData( xNew->getData() );
[ # # ][ # # ]
[ # # ]
175 [ # # ][ # # ]: 0 : xDataAccess->setRowDescriptions( xNew->getRowDescriptions() );
[ # # ][ # # ]
[ # # ]
176 [ # # ][ # # ]: 0 : xDataAccess->setColumnDescriptions( xNew->getColumnDescriptions() );
[ # # ][ # # ]
[ # # ]
177 : 0 : }
178 : 0 : }
179 : : }
180 : :
181 : : Reference< XChartData > m_xDataToApply;
182 : : };
183 : :
184 : : //--------------------------------------------------------------------------
185 : :
186 [ - + ]: 10 : struct lcl_DataOperator : public lcl_Operator
187 : : {
188 : 10 : lcl_DataOperator( const Sequence< Sequence< double > >& rData )
189 : : : lcl_Operator()
190 : 10 : , m_rData( rData )
191 : : {
192 : 10 : }
193 : :
194 : 10 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
195 : : {
196 [ + - ]: 10 : if( xDataAccess.is() )
197 [ + - ]: 10 : xDataAccess->setData( lcl_getNANInsteadDBL_MIN( m_rData ) );
198 : 10 : }
199 : :
200 : : const Sequence< Sequence< double > >& m_rData;
201 : : };
202 : :
203 : : //--------------------------------------------------------------------------
204 : :
205 [ - + ]: 2 : struct lcl_RowDescriptionsOperator : public lcl_Operator
206 : : {
207 : 2 : lcl_RowDescriptionsOperator( const Sequence< OUString >& rRowDescriptions
208 : : , const Reference< chart2::XChartDocument >& xChartDoc )
209 : : : lcl_Operator()
210 : : , m_rRowDescriptions( rRowDescriptions )
211 : : , m_xChartDoc(xChartDoc)
212 : 2 : , m_bDataInColumns(true)
213 : : {
214 : 2 : }
215 : :
216 : 0 : virtual bool setsCategories( bool bDataInColumns )
217 : : {
218 : 0 : m_bDataInColumns = bDataInColumns;
219 : 0 : return bDataInColumns;
220 : : }
221 : :
222 : 2 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
223 : : {
224 [ + - ]: 2 : if( xDataAccess.is() )
225 : : {
226 : 2 : xDataAccess->setRowDescriptions( m_rRowDescriptions );
227 [ + - ]: 2 : if( m_bDataInColumns )
228 : 2 : DiagramHelper::switchToTextCategories( m_xChartDoc );
229 : : }
230 : 2 : }
231 : :
232 : : const Sequence< OUString >& m_rRowDescriptions;
233 : : Reference< chart2::XChartDocument > m_xChartDoc;
234 : : bool m_bDataInColumns;
235 : : };
236 : :
237 : : //--------------------------------------------------------------------------
238 : :
239 [ # # ]: 0 : struct lcl_ComplexRowDescriptionsOperator : public lcl_Operator
240 : : {
241 : 0 : lcl_ComplexRowDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexRowDescriptions
242 : : , const Reference< chart2::XChartDocument >& xChartDoc )
243 : : : lcl_Operator()
244 : : , m_rComplexRowDescriptions( rComplexRowDescriptions )
245 : : , m_xChartDoc(xChartDoc)
246 : 0 : , m_bDataInColumns(true)
247 : : {
248 : 0 : }
249 : :
250 : 0 : virtual bool setsCategories( bool bDataInColumns )
251 : : {
252 : 0 : m_bDataInColumns = bDataInColumns;
253 : 0 : return bDataInColumns;
254 : : }
255 : :
256 : 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
257 : : {
258 [ # # ]: 0 : if( xDataAccess.is() )
259 : : {
260 : 0 : xDataAccess->setComplexRowDescriptions( m_rComplexRowDescriptions );
261 [ # # ]: 0 : if( m_bDataInColumns )
262 : 0 : DiagramHelper::switchToTextCategories( m_xChartDoc );
263 : : }
264 : 0 : }
265 : :
266 : : const Sequence< Sequence< OUString > >& m_rComplexRowDescriptions;
267 : : Reference< chart2::XChartDocument > m_xChartDoc;
268 : : bool m_bDataInColumns;
269 : : };
270 : : //--------------------------------------------------------------------------
271 : :
272 [ # # ]: 0 : struct lcl_AnyRowDescriptionsOperator : public lcl_Operator
273 : : {
274 : 0 : lcl_AnyRowDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyRowDescriptions )
275 : : : lcl_Operator()
276 : 0 : , m_rAnyRowDescriptions( rAnyRowDescriptions )
277 : : {
278 : 0 : }
279 : :
280 : 0 : virtual bool setsCategories( bool bDataInColumns )
281 : : {
282 : 0 : return bDataInColumns;
283 : : }
284 : :
285 : 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
286 : : {
287 [ # # ]: 0 : if( xDataAccess.is() )
288 : 0 : xDataAccess->setAnyRowDescriptions( m_rAnyRowDescriptions );
289 : 0 : }
290 : :
291 : : const Sequence< Sequence< uno::Any > >& m_rAnyRowDescriptions;
292 : : };
293 : :
294 : : //--------------------------------------------------------------------------
295 : :
296 [ - + ]: 2 : struct lcl_ColumnDescriptionsOperator : public lcl_Operator
297 : : {
298 : 2 : lcl_ColumnDescriptionsOperator( const Sequence< OUString >& rColumnDescriptions
299 : : , const Reference< chart2::XChartDocument >& xChartDoc )
300 : : : lcl_Operator()
301 : : , m_rColumnDescriptions( rColumnDescriptions )
302 : : , m_xChartDoc(xChartDoc)
303 : 2 : , m_bDataInColumns(true)
304 : : {
305 : 2 : }
306 : :
307 : 0 : virtual bool setsCategories( bool bDataInColumns )
308 : : {
309 : 0 : m_bDataInColumns = bDataInColumns;
310 : 0 : return !bDataInColumns;
311 : : }
312 : :
313 : 2 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
314 : : {
315 [ + - ]: 2 : if( xDataAccess.is() )
316 : : {
317 : 2 : xDataAccess->setColumnDescriptions( m_rColumnDescriptions );
318 [ - + ]: 2 : if( !m_bDataInColumns )
319 : 0 : DiagramHelper::switchToTextCategories( m_xChartDoc );
320 : : }
321 : 2 : }
322 : :
323 : : const Sequence< OUString >& m_rColumnDescriptions;
324 : : Reference< chart2::XChartDocument > m_xChartDoc;
325 : : bool m_bDataInColumns;
326 : : };
327 : :
328 : : //--------------------------------------------------------------------------
329 : :
330 [ # # ]: 0 : struct lcl_ComplexColumnDescriptionsOperator : public lcl_Operator
331 : : {
332 : 0 : lcl_ComplexColumnDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexColumnDescriptions
333 : : , const Reference< chart2::XChartDocument >& xChartDoc )
334 : : : lcl_Operator()
335 : : , m_rComplexColumnDescriptions( rComplexColumnDescriptions )
336 : : , m_xChartDoc(xChartDoc)
337 : 0 : , m_bDataInColumns(true)
338 : : {
339 : 0 : }
340 : :
341 : 0 : virtual bool setsCategories( bool bDataInColumns )
342 : : {
343 : 0 : m_bDataInColumns = bDataInColumns;
344 : 0 : return !bDataInColumns;
345 : : }
346 : :
347 : 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
348 : : {
349 [ # # ]: 0 : if( xDataAccess.is() )
350 : : {
351 : 0 : xDataAccess->setComplexColumnDescriptions( m_rComplexColumnDescriptions );
352 [ # # ]: 0 : if( !m_bDataInColumns )
353 : 0 : DiagramHelper::switchToTextCategories( m_xChartDoc );
354 : : }
355 : 0 : }
356 : :
357 : : const Sequence< Sequence< OUString > >& m_rComplexColumnDescriptions;
358 : : Reference< chart2::XChartDocument > m_xChartDoc;
359 : : bool m_bDataInColumns;
360 : : };
361 : :
362 : : //--------------------------------------------------------------------------
363 : :
364 [ # # ]: 0 : struct lcl_AnyColumnDescriptionsOperator : public lcl_Operator
365 : : {
366 : 0 : lcl_AnyColumnDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyColumnDescriptions )
367 : : : lcl_Operator()
368 : 0 : , m_rAnyColumnDescriptions( rAnyColumnDescriptions )
369 : : {
370 : 0 : }
371 : :
372 : 0 : virtual bool setsCategories( bool bDataInColumns )
373 : : {
374 : 0 : return bDataInColumns;
375 : : }
376 : :
377 : 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
378 : : {
379 [ # # ]: 0 : if( xDataAccess.is() )
380 : 0 : xDataAccess->setAnyColumnDescriptions( m_rAnyColumnDescriptions );
381 : 0 : }
382 : :
383 : : const Sequence< Sequence< uno::Any > >& m_rAnyColumnDescriptions;
384 : : };
385 : :
386 : : //--------------------------------------------------------------------------
387 : :
388 [ # # ]: 0 : struct lcl_DateCategoriesOperator : public lcl_Operator
389 : : {
390 : 0 : lcl_DateCategoriesOperator( const Sequence< double >& rDates )
391 : : : lcl_Operator()
392 : 0 : , m_rDates( rDates )
393 : : {
394 : 0 : }
395 : :
396 : 0 : virtual bool setsCategories( bool /*bDataInColumns*/ )
397 : : {
398 : 0 : return true;
399 : : }
400 : :
401 : 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
402 : : {
403 [ # # ]: 0 : Reference< XDateCategories > xDateCategories( xDataAccess, uno::UNO_QUERY );
404 [ # # ]: 0 : if( xDateCategories.is() )
405 [ # # ][ # # ]: 0 : xDateCategories->setDateCategories( m_rDates );
406 : 0 : }
407 : :
408 : : const Sequence< double >& m_rDates;
409 : : };
410 : :
411 : : //--------------------------------------------------------------------------
412 : :
413 : 21 : ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) :
414 : : m_spChart2ModelContact( spChart2ModelContact ),
415 [ + - ][ + - ]: 21 : m_aEventListenerContainer( m_aMutex )
[ + - ]
416 : : {
417 [ + - ]: 21 : osl_incrementInterlockedCount( &m_refCount );
418 [ + - ]: 21 : initDataAccess();
419 [ + - ]: 21 : osl_decrementInterlockedCount( &m_refCount );
420 : 21 : }
421 : :
422 : 0 : ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact,
423 : : const Reference< XChartData >& xNewData ) :
424 : : m_spChart2ModelContact( spChart2ModelContact ),
425 [ # # ][ # # ]: 0 : m_aEventListenerContainer( m_aMutex )
[ # # ]
426 : : {
427 [ # # ]: 0 : osl_incrementInterlockedCount( &m_refCount );
428 [ # # ]: 0 : lcl_AllOperator aOperator( xNewData );
429 [ # # ]: 0 : applyData( aOperator );
430 [ # # ]: 0 : osl_decrementInterlockedCount( &m_refCount );
431 : 0 : }
432 : :
433 [ + - ][ + - ]: 21 : ChartDataWrapper::~ChartDataWrapper()
[ + - ]
434 : : {
435 : : // @todo: implement XComponent and call this in dispose(). In the DTOR the
436 : : // ref-count is 0, thus creating a stack reference to this calls the DTOR at
437 : : // the end of the block recursively
438 : : // uno::Reference< uno::XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
439 : : // m_aEventListenerContainer.disposeAndClear( lang::EventObject( xSource ) );
440 [ - + ]: 42 : }
441 : :
442 : : // ____ XChartDataArray (read)____
443 : 12 : Sequence< Sequence< double > > SAL_CALL ChartDataWrapper::getData()
444 : : throw (uno::RuntimeException)
445 : : {
446 : 12 : initDataAccess();
447 [ + - ]: 12 : if( m_xDataAccess.is() )
448 [ + - ]: 12 : return lcl_getDBL_MINInsteadNAN( m_xDataAccess->getData() );
449 : 12 : return Sequence< Sequence< double > >();
450 : : }
451 : 19 : Sequence< OUString > SAL_CALL ChartDataWrapper::getRowDescriptions()
452 : : throw (uno::RuntimeException)
453 : : {
454 : 19 : initDataAccess();
455 [ + - ]: 19 : if( m_xDataAccess.is() )
456 : 19 : return m_xDataAccess->getRowDescriptions();
457 : 19 : return Sequence< OUString >();
458 : : }
459 : 10 : Sequence< OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions()
460 : : throw (uno::RuntimeException)
461 : : {
462 : 10 : initDataAccess();
463 [ + - ]: 10 : if( m_xDataAccess.is() )
464 : 10 : return m_xDataAccess->getColumnDescriptions();
465 : 10 : return Sequence< OUString > ();
466 : : }
467 : :
468 : : // ____ XComplexDescriptionAccess (read) ____
469 : 0 : Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexRowDescriptions() throw (uno::RuntimeException)
470 : : {
471 : 0 : initDataAccess();
472 [ # # ]: 0 : if( m_xDataAccess.is() )
473 : 0 : return m_xDataAccess->getComplexRowDescriptions();
474 : 0 : return Sequence< Sequence< OUString > >();
475 : : }
476 : 0 : Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexColumnDescriptions() throw (uno::RuntimeException)
477 : : {
478 : 0 : initDataAccess();
479 [ # # ]: 0 : if( m_xDataAccess.is() )
480 : 0 : return m_xDataAccess->getComplexColumnDescriptions();
481 : 0 : return Sequence< Sequence< OUString > >();
482 : : }
483 : :
484 : : // ____ XAnyDescriptionAccess (read) ____
485 : 9 : Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyRowDescriptions() throw (uno::RuntimeException)
486 : : {
487 : 9 : initDataAccess();
488 [ + - ]: 9 : if( m_xDataAccess.is() )
489 : 9 : return m_xDataAccess->getAnyRowDescriptions();
490 : 9 : return Sequence< Sequence< uno::Any > >();
491 : : }
492 : 0 : Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyColumnDescriptions() throw (uno::RuntimeException)
493 : : {
494 : 0 : initDataAccess();
495 [ # # ]: 0 : if( m_xDataAccess.is() )
496 : 0 : return m_xDataAccess->getAnyColumnDescriptions();
497 : 0 : return Sequence< Sequence< uno::Any > >();
498 : : }
499 : :
500 : : // ____ XDateCategories (read) ____
501 : 0 : Sequence< double > SAL_CALL ChartDataWrapper::getDateCategories() throw (uno::RuntimeException)
502 : : {
503 [ # # ]: 0 : initDataAccess();
504 [ # # ]: 0 : Reference< XDateCategories > xDateCategories( m_xDataAccess, uno::UNO_QUERY );
505 [ # # ]: 0 : if( xDateCategories.is() )
506 [ # # ][ # # ]: 0 : return xDateCategories->getDateCategories();
507 [ # # ]: 0 : return Sequence< double >();
508 : : }
509 : :
510 : : // ____ XChartDataArray (write)____
511 : 10 : void SAL_CALL ChartDataWrapper::setData( const Sequence< Sequence< double > >& rData )
512 : : throw (uno::RuntimeException)
513 : : {
514 : 10 : lcl_DataOperator aOperator( rData );
515 [ + - ]: 10 : applyData( aOperator );
516 : 10 : }
517 : 2 : void SAL_CALL ChartDataWrapper::setRowDescriptions( const Sequence< OUString >& rRowDescriptions )
518 : : throw (uno::RuntimeException)
519 : : {
520 [ + - ][ + - ]: 2 : lcl_RowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() );
521 [ + - ]: 2 : applyData( aOperator );
522 : 2 : }
523 : 2 : void SAL_CALL ChartDataWrapper::setColumnDescriptions( const Sequence< OUString >& rColumnDescriptions )
524 : : throw (uno::RuntimeException)
525 : : {
526 [ + - ][ + - ]: 2 : lcl_ColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() );
527 [ + - ]: 2 : applyData( aOperator );
528 : 2 : }
529 : :
530 : : // ____ XComplexDescriptionAccess (write) ____
531 : 0 : void SAL_CALL ChartDataWrapper::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rRowDescriptions ) throw (uno::RuntimeException)
532 : : {
533 [ # # ][ # # ]: 0 : lcl_ComplexRowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() );
534 [ # # ]: 0 : applyData( aOperator );
535 : 0 : }
536 : 0 : void SAL_CALL ChartDataWrapper::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rColumnDescriptions ) throw (uno::RuntimeException)
537 : : {
538 [ # # ][ # # ]: 0 : lcl_ComplexColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() );
539 [ # # ]: 0 : applyData( aOperator );
540 : 0 : }
541 : :
542 : : // ____ XAnyDescriptionAccess (write) ____
543 : 0 : void SAL_CALL ChartDataWrapper::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& rRowDescriptions ) throw (uno::RuntimeException)
544 : : {
545 : 0 : lcl_AnyRowDescriptionsOperator aOperator( rRowDescriptions );
546 [ # # ]: 0 : applyData( aOperator );
547 : 0 : }
548 : 0 : void SAL_CALL ChartDataWrapper::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& rColumnDescriptions ) throw (uno::RuntimeException)
549 : : {
550 : 0 : lcl_AnyColumnDescriptionsOperator aOperator( rColumnDescriptions );
551 [ # # ]: 0 : applyData( aOperator );
552 : 0 : }
553 : :
554 : : // ____ XDateCategories (write) ____
555 : 0 : void SAL_CALL ChartDataWrapper::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException)
556 : : {
557 [ # # ]: 0 : Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
558 [ # # ][ # # ]: 0 : ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ));
559 : 0 : lcl_DateCategoriesOperator aOperator( rDates );
560 [ # # ]: 0 : applyData( aOperator );
561 [ # # ][ # # ]: 0 : DiagramHelper::switchToDateCategories( xChartDoc );
562 : 0 : }
563 : :
564 : : //--------------------------------------------------------------------------------------
565 : :
566 : : // ____ XChartData (base of XChartDataArray) ____
567 : 8 : void SAL_CALL ChartDataWrapper::addChartDataChangeEventListener(
568 : : const uno::Reference<
569 : : ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
570 : : throw (uno::RuntimeException)
571 : : {
572 : 8 : m_aEventListenerContainer.addInterface( aListener );
573 : 8 : }
574 : :
575 : 8 : void SAL_CALL ChartDataWrapper::removeChartDataChangeEventListener(
576 : : const uno::Reference<
577 : : ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
578 : : throw (uno::RuntimeException)
579 : : {
580 : 8 : m_aEventListenerContainer.removeInterface( aListener );
581 : 8 : }
582 : :
583 : 4 : double SAL_CALL ChartDataWrapper::getNotANumber()
584 : : throw (uno::RuntimeException)
585 : : {
586 : 4 : return DBL_MIN;
587 : : }
588 : :
589 : 8 : sal_Bool SAL_CALL ChartDataWrapper::isNotANumber( double nNumber )
590 : : throw (uno::RuntimeException)
591 : : {
592 : : return DBL_MIN == nNumber
593 : 4 : || ::rtl::math::isNan( nNumber )
594 [ + + + - ]: 12 : || ::rtl::math::isInf( nNumber );
[ - + ]
595 : : }
596 : :
597 : : // ____ XComponent ____
598 : 21 : void SAL_CALL ChartDataWrapper::dispose()
599 : : throw (uno::RuntimeException)
600 : : {
601 [ + - ][ + - ]: 21 : m_aEventListenerContainer.disposeAndClear( lang::EventObject( static_cast< ::cppu::OWeakObject* >( this )));
[ + - ]
602 : 21 : m_xDataAccess=0;
603 : 21 : }
604 : :
605 : 0 : void SAL_CALL ChartDataWrapper::addEventListener(
606 : : const uno::Reference< lang::XEventListener > & xListener )
607 : : throw (uno::RuntimeException)
608 : : {
609 : 0 : m_aEventListenerContainer.addInterface( xListener );
610 : 0 : }
611 : :
612 : 0 : void SAL_CALL ChartDataWrapper::removeEventListener(
613 : : const uno::Reference< lang::XEventListener >& aListener )
614 : : throw (uno::RuntimeException)
615 : : {
616 : 0 : m_aEventListenerContainer.removeInterface( aListener );
617 : 0 : }
618 : :
619 : : // ____ XEventListener ____
620 : 0 : void SAL_CALL ChartDataWrapper::disposing( const lang::EventObject& /* Source */ )
621 : : throw (uno::RuntimeException)
622 : : {
623 : 0 : }
624 : :
625 : :
626 : 14 : void ChartDataWrapper::fireChartDataChangeEvent(
627 : : ::com::sun::star::chart::ChartDataChangeEvent& aEvent )
628 : : {
629 [ + - ][ + + ]: 14 : if( ! m_aEventListenerContainer.getLength() )
630 : 14 : return;
631 : :
632 [ + - ]: 8 : uno::Reference< uno::XInterface > xSrc( static_cast< cppu::OWeakObject* >( this ));
633 : : OSL_ASSERT( xSrc.is());
634 [ + - ]: 8 : if( xSrc.is() )
635 [ + - ]: 8 : aEvent.Source = xSrc;
636 : :
637 [ + - ]: 8 : ::cppu::OInterfaceIteratorHelper aIter( m_aEventListenerContainer );
638 : :
639 [ + + ]: 20 : while( aIter.hasMoreElements() )
640 : : {
641 : : uno::Reference<
642 : : ::com::sun::star::chart::XChartDataChangeEventListener > xListener(
643 [ + - ][ + - ]: 12 : aIter.next(), uno::UNO_QUERY );
644 [ + - ]: 12 : if( xListener.is() )
645 [ + - ][ + - ]: 12 : xListener->chartDataChanged( aEvent );
646 [ + - ]: 26 : }
647 : : }
648 : :
649 : : // --------------------------------------------------------------------------------
650 : :
651 : 14 : void ChartDataWrapper::switchToInternalDataProvider()
652 : : {
653 : : //create an internal data provider that is connected to the model
654 [ + - ]: 14 : Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
655 [ + - ]: 14 : if( xChartDoc.is() )
656 [ + - ][ + - ]: 14 : xChartDoc->createInternalDataProvider( true /*bCloneExistingData*/ );
657 [ + - ]: 14 : initDataAccess();
658 : 14 : }
659 : :
660 : 85 : void ChartDataWrapper::initDataAccess()
661 : : {
662 [ + - ]: 85 : Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
663 [ - + ]: 85 : if( !xChartDoc.is() )
664 : 85 : return;
665 [ + - ][ + - ]: 85 : if( xChartDoc->hasInternalDataProvider() )
[ + + ]
666 [ + - ][ + - ]: 70 : m_xDataAccess = Reference< XAnyDescriptionAccess >( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW );
[ + - ][ + - ]
667 : : else
668 : : {
669 : : //create a separate "internal data provider" that is not connected to the model
670 : : m_xDataAccess = Reference< XAnyDescriptionAccess >( ChartModelHelper::createInternalDataProvider(
671 [ + - ][ + - ]: 85 : xChartDoc, false /*bConnectToModel*/ ), uno::UNO_QUERY_THROW );
[ + - ]
672 [ + - ]: 85 : }
673 : : }
674 : :
675 : 14 : void ChartDataWrapper::applyData( lcl_Operator& rDataOperator )
676 : : {
677 : : //bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions
678 [ + - ]: 14 : Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
679 [ - + ]: 14 : if( !xChartDoc.is() )
680 : : return;
681 : :
682 : : // remember some diagram properties to reset later
683 : 14 : sal_Bool bStacked = sal_False;
684 : 14 : sal_Bool bPercent = sal_False;
685 : 14 : sal_Bool bDeep = sal_False;
686 [ + - ]: 14 : uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartDoc, uno::UNO_QUERY );
687 : : OSL_ASSERT( xOldDoc.is());
688 [ + - ][ + - ]: 14 : uno::Reference< beans::XPropertySet > xDiaProp( xOldDoc->getDiagram(), uno::UNO_QUERY );
[ + - ]
689 [ + - ]: 14 : if( xDiaProp.is())
690 : : {
691 [ + - ][ + - ]: 14 : xDiaProp->getPropertyValue("Stacked") >>= bStacked;
692 [ + - ][ + - ]: 14 : xDiaProp->getPropertyValue("Percent") >>= bPercent;
693 [ + - ][ + - ]: 14 : xDiaProp->getPropertyValue("Deep") >>= bDeep;
694 : : }
695 : :
696 : : //detect arguments for the new data source
697 : 14 : ::rtl::OUString aRangeString;
698 : 14 : bool bUseColumns = true;
699 : 14 : bool bFirstCellAsLabel = true;
700 : 14 : bool bHasCategories = true;
701 [ + - ]: 14 : uno::Sequence< sal_Int32 > aSequenceMapping;
702 : :
703 : : DataSourceHelper::detectRangeSegmentation(
704 : : uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ),
705 [ + - ][ + - ]: 14 : aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
706 : :
707 [ # # ][ # # ]: 14 : if( !bHasCategories && rDataOperator.setsCategories( bUseColumns ) )
[ - + ][ - + ]
708 : 0 : bHasCategories = true;
709 : :
710 : 14 : aRangeString = "all";
711 : : uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments(
712 [ + - ]: 14 : aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) );
713 : :
714 : :
715 : : // /-- locked controllers
716 [ + - ][ + - ]: 14 : ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ));
717 : :
718 : : // create and attach new data source
719 [ + - ]: 14 : switchToInternalDataProvider();
720 [ + - ]: 14 : rDataOperator.apply(m_xDataAccess);
721 [ + - ][ + - ]: 14 : uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
722 : : OSL_ASSERT( xDataProvider.is() );
723 [ - + ]: 14 : if( !xDataProvider.is() )
724 : : return;
725 [ + - ][ + - ]: 14 : uno::Reference< chart2::data::XDataSource > xSource( xDataProvider->createDataSource( aArguments ) );
726 : :
727 [ + - ][ + - ]: 14 : uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram() );
728 [ + - ]: 14 : if( xDia.is() )
729 [ + - ][ + - ]: 14 : xDia->setDiagramData( xSource, aArguments );
730 : :
731 : : //correct stacking mode
732 [ + - ][ + - ]: 14 : if( bStacked || bPercent || bDeep )
[ - + ]
733 : : {
734 : 0 : StackMode eStackMode = StackMode_Y_STACKED;
735 [ # # ]: 0 : if( bDeep )
736 : 0 : eStackMode = StackMode_Z_STACKED;
737 [ # # ]: 0 : else if( bPercent )
738 : 0 : eStackMode = StackMode_Y_STACKED_PERCENT;
739 [ # # ]: 0 : DiagramHelper::setStackMode( xDia, eStackMode );
740 : : }
741 : :
742 : : // notify listeners
743 : : ::com::sun::star::chart::ChartDataChangeEvent aEvent(
744 : : static_cast< ::cppu::OWeakObject* >( this ),
745 [ + - ][ + - ]: 14 : ::com::sun::star::chart::ChartDataChangeType_ALL, 0, 0, 0, 0 );
746 [ + - ][ - + ]: 14 : fireChartDataChangeEvent( aEvent );
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ][ - + ]
[ - + ][ - + ]
[ - + ][ + - ]
[ + - ]
747 : : // \-- locked controllers
748 : : }
749 : :
750 : : // --------------------------------------------------------------------------------
751 : :
752 : 0 : uno::Sequence< ::rtl::OUString > ChartDataWrapper::getSupportedServiceNames_Static()
753 : : {
754 : 0 : uno::Sequence< ::rtl::OUString > aServices( 2 );
755 [ # # ]: 0 : aServices[ 0 ] = "com.sun.star.chart.ChartDataArray";
756 [ # # ]: 0 : aServices[ 1 ] = "com.sun.star.chart.ChartData";
757 : :
758 : 0 : return aServices;
759 : : }
760 : :
761 : : // ================================================================================
762 : :
763 : : // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
764 [ # # ][ # # ]: 0 : APPHELPER_XSERVICEINFO_IMPL( ChartDataWrapper, lcl_aServiceName );
[ # # ][ # # ]
[ # # ]
765 : :
766 : : } // namespace wrapper
767 [ + - ][ + - ]: 48 : } // namespace chart
768 : :
769 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|