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 1 : static const ::rtl::OUString lcl_aServiceName(
66 : RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" ));
67 :
68 0 : uno::Sequence< uno::Sequence< double > > lcl_getNANInsteadDBL_MIN( const uno::Sequence< uno::Sequence< double > >& rData )
69 : {
70 0 : uno::Sequence< uno::Sequence< double > > aRet;
71 0 : const sal_Int32 nOuterSize = rData.getLength();
72 0 : aRet.realloc( nOuterSize );
73 0 : for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
74 : {
75 0 : sal_Int32 nInnerSize = rData[nOuter].getLength();
76 0 : aRet[nOuter].realloc( nInnerSize );
77 0 : for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
78 : {
79 0 : aRet[nOuter][nInner] = rData[nOuter][nInner];
80 0 : double& rValue = aRet[nOuter][nInner];
81 0 : if( rValue == DBL_MIN )
82 0 : ::rtl::math::setNan( &rValue );
83 : }
84 : }
85 0 : return aRet;
86 : }
87 :
88 0 : uno::Sequence< uno::Sequence< double > > lcl_getDBL_MINInsteadNAN( const uno::Sequence< uno::Sequence< double > >& rData )
89 : {
90 0 : uno::Sequence< uno::Sequence< double > > aRet;
91 0 : const sal_Int32 nOuterSize = rData.getLength();
92 0 : aRet.realloc( nOuterSize );
93 0 : for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter )
94 : {
95 0 : sal_Int32 nInnerSize = rData[nOuter].getLength();
96 0 : aRet[nOuter].realloc( nInnerSize );
97 0 : for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner )
98 : {
99 0 : aRet[nOuter][nInner] = rData[nOuter][nInner];
100 0 : double& rValue = aRet[nOuter][nInner];
101 0 : if( ::rtl::math::isNan( rValue ) )
102 0 : rValue = DBL_MIN;
103 : }
104 : }
105 0 : 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 0 : lcl_Operator()
122 0 : {
123 0 : }
124 0 : virtual ~lcl_Operator()
125 0 : {
126 0 : }
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 0 : struct lcl_DataOperator : public lcl_Operator
187 : {
188 0 : lcl_DataOperator( const Sequence< Sequence< double > >& rData )
189 : : lcl_Operator()
190 0 : , m_rData( rData )
191 : {
192 0 : }
193 :
194 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
195 : {
196 0 : if( xDataAccess.is() )
197 0 : xDataAccess->setData( lcl_getNANInsteadDBL_MIN( m_rData ) );
198 0 : }
199 :
200 : const Sequence< Sequence< double > >& m_rData;
201 : };
202 :
203 : //--------------------------------------------------------------------------
204 :
205 0 : struct lcl_RowDescriptionsOperator : public lcl_Operator
206 : {
207 0 : lcl_RowDescriptionsOperator( const Sequence< OUString >& rRowDescriptions
208 : , const Reference< chart2::XChartDocument >& xChartDoc )
209 : : lcl_Operator()
210 : , m_rRowDescriptions( rRowDescriptions )
211 : , m_xChartDoc(xChartDoc)
212 0 : , m_bDataInColumns(true)
213 : {
214 0 : }
215 :
216 0 : virtual bool setsCategories( bool bDataInColumns )
217 : {
218 0 : m_bDataInColumns = bDataInColumns;
219 0 : return bDataInColumns;
220 : }
221 :
222 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
223 : {
224 0 : if( xDataAccess.is() )
225 : {
226 0 : xDataAccess->setRowDescriptions( m_rRowDescriptions );
227 0 : if( m_bDataInColumns )
228 0 : DiagramHelper::switchToTextCategories( m_xChartDoc );
229 : }
230 0 : }
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 0 : struct lcl_ColumnDescriptionsOperator : public lcl_Operator
297 : {
298 0 : lcl_ColumnDescriptionsOperator( const Sequence< OUString >& rColumnDescriptions
299 : , const Reference< chart2::XChartDocument >& xChartDoc )
300 : : lcl_Operator()
301 : , m_rColumnDescriptions( rColumnDescriptions )
302 : , m_xChartDoc(xChartDoc)
303 0 : , m_bDataInColumns(true)
304 : {
305 0 : }
306 :
307 0 : virtual bool setsCategories( bool bDataInColumns )
308 : {
309 0 : m_bDataInColumns = bDataInColumns;
310 0 : return !bDataInColumns;
311 : }
312 :
313 0 : virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess )
314 : {
315 0 : if( xDataAccess.is() )
316 : {
317 0 : xDataAccess->setColumnDescriptions( m_rColumnDescriptions );
318 0 : if( !m_bDataInColumns )
319 0 : DiagramHelper::switchToTextCategories( m_xChartDoc );
320 : }
321 0 : }
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 0 : ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) :
414 : m_spChart2ModelContact( spChart2ModelContact ),
415 0 : m_aEventListenerContainer( m_aMutex )
416 : {
417 0 : osl_atomic_increment( &m_refCount );
418 0 : initDataAccess();
419 0 : osl_atomic_decrement( &m_refCount );
420 0 : }
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_atomic_increment( &m_refCount );
428 0 : lcl_AllOperator aOperator( xNewData );
429 0 : applyData( aOperator );
430 0 : osl_atomic_decrement( &m_refCount );
431 0 : }
432 :
433 0 : 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 0 : }
441 :
442 : // ____ XChartDataArray (read)____
443 0 : Sequence< Sequence< double > > SAL_CALL ChartDataWrapper::getData()
444 : throw (uno::RuntimeException)
445 : {
446 0 : initDataAccess();
447 0 : if( m_xDataAccess.is() )
448 0 : return lcl_getDBL_MINInsteadNAN( m_xDataAccess->getData() );
449 0 : return Sequence< Sequence< double > >();
450 : }
451 0 : Sequence< OUString > SAL_CALL ChartDataWrapper::getRowDescriptions()
452 : throw (uno::RuntimeException)
453 : {
454 0 : initDataAccess();
455 0 : if( m_xDataAccess.is() )
456 0 : return m_xDataAccess->getRowDescriptions();
457 0 : return Sequence< OUString >();
458 : }
459 0 : Sequence< OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions()
460 : throw (uno::RuntimeException)
461 : {
462 0 : initDataAccess();
463 0 : if( m_xDataAccess.is() )
464 0 : return m_xDataAccess->getColumnDescriptions();
465 0 : 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 0 : Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyRowDescriptions() throw (uno::RuntimeException)
486 : {
487 0 : initDataAccess();
488 0 : if( m_xDataAccess.is() )
489 0 : return m_xDataAccess->getAnyRowDescriptions();
490 0 : 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 0 : void SAL_CALL ChartDataWrapper::setData( const Sequence< Sequence< double > >& rData )
512 : throw (uno::RuntimeException)
513 : {
514 0 : lcl_DataOperator aOperator( rData );
515 0 : applyData( aOperator );
516 0 : }
517 0 : void SAL_CALL ChartDataWrapper::setRowDescriptions( const Sequence< OUString >& rRowDescriptions )
518 : throw (uno::RuntimeException)
519 : {
520 0 : lcl_RowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() );
521 0 : applyData( aOperator );
522 0 : }
523 0 : void SAL_CALL ChartDataWrapper::setColumnDescriptions( const Sequence< OUString >& rColumnDescriptions )
524 : throw (uno::RuntimeException)
525 : {
526 0 : lcl_ColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() );
527 0 : applyData( aOperator );
528 0 : }
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 0 : void SAL_CALL ChartDataWrapper::addChartDataChangeEventListener(
568 : const uno::Reference<
569 : ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
570 : throw (uno::RuntimeException)
571 : {
572 0 : m_aEventListenerContainer.addInterface( aListener );
573 0 : }
574 :
575 0 : void SAL_CALL ChartDataWrapper::removeChartDataChangeEventListener(
576 : const uno::Reference<
577 : ::com::sun::star::chart::XChartDataChangeEventListener >& aListener )
578 : throw (uno::RuntimeException)
579 : {
580 0 : m_aEventListenerContainer.removeInterface( aListener );
581 0 : }
582 :
583 0 : double SAL_CALL ChartDataWrapper::getNotANumber()
584 : throw (uno::RuntimeException)
585 : {
586 0 : return DBL_MIN;
587 : }
588 :
589 0 : sal_Bool SAL_CALL ChartDataWrapper::isNotANumber( double nNumber )
590 : throw (uno::RuntimeException)
591 : {
592 : return DBL_MIN == nNumber
593 0 : || ::rtl::math::isNan( nNumber )
594 0 : || ::rtl::math::isInf( nNumber );
595 : }
596 :
597 : // ____ XComponent ____
598 0 : void SAL_CALL ChartDataWrapper::dispose()
599 : throw (uno::RuntimeException)
600 : {
601 0 : m_aEventListenerContainer.disposeAndClear( lang::EventObject( static_cast< ::cppu::OWeakObject* >( this )));
602 0 : m_xDataAccess=0;
603 0 : }
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 0 : void ChartDataWrapper::fireChartDataChangeEvent(
627 : ::com::sun::star::chart::ChartDataChangeEvent& aEvent )
628 : {
629 0 : if( ! m_aEventListenerContainer.getLength() )
630 0 : return;
631 :
632 0 : uno::Reference< uno::XInterface > xSrc( static_cast< cppu::OWeakObject* >( this ));
633 : OSL_ASSERT( xSrc.is());
634 0 : if( xSrc.is() )
635 0 : aEvent.Source = xSrc;
636 :
637 0 : ::cppu::OInterfaceIteratorHelper aIter( m_aEventListenerContainer );
638 :
639 0 : while( aIter.hasMoreElements() )
640 : {
641 : uno::Reference<
642 : ::com::sun::star::chart::XChartDataChangeEventListener > xListener(
643 0 : aIter.next(), uno::UNO_QUERY );
644 0 : if( xListener.is() )
645 0 : xListener->chartDataChanged( aEvent );
646 0 : }
647 : }
648 :
649 : // --------------------------------------------------------------------------------
650 :
651 0 : void ChartDataWrapper::switchToInternalDataProvider()
652 : {
653 : //create an internal data provider that is connected to the model
654 0 : Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
655 0 : if( xChartDoc.is() )
656 0 : xChartDoc->createInternalDataProvider( true /*bCloneExistingData*/ );
657 0 : initDataAccess();
658 0 : }
659 :
660 0 : void ChartDataWrapper::initDataAccess()
661 : {
662 0 : Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
663 0 : if( !xChartDoc.is() )
664 0 : return;
665 0 : if( xChartDoc->hasInternalDataProvider() )
666 0 : 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 0 : xChartDoc, false /*bConnectToModel*/ ), uno::UNO_QUERY_THROW );
672 0 : }
673 : }
674 :
675 0 : void ChartDataWrapper::applyData( lcl_Operator& rDataOperator )
676 : {
677 : //bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions
678 0 : Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() );
679 0 : if( !xChartDoc.is() )
680 : return;
681 :
682 : // remember some diagram properties to reset later
683 0 : sal_Bool bStacked = sal_False;
684 0 : sal_Bool bPercent = sal_False;
685 0 : sal_Bool bDeep = sal_False;
686 0 : uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartDoc, uno::UNO_QUERY );
687 : OSL_ASSERT( xOldDoc.is());
688 0 : uno::Reference< beans::XPropertySet > xDiaProp( xOldDoc->getDiagram(), uno::UNO_QUERY );
689 0 : if( xDiaProp.is())
690 : {
691 0 : xDiaProp->getPropertyValue("Stacked") >>= bStacked;
692 0 : xDiaProp->getPropertyValue("Percent") >>= bPercent;
693 0 : xDiaProp->getPropertyValue("Deep") >>= bDeep;
694 : }
695 :
696 : //detect arguments for the new data source
697 0 : ::rtl::OUString aRangeString;
698 0 : bool bUseColumns = true;
699 0 : bool bFirstCellAsLabel = true;
700 0 : bool bHasCategories = true;
701 0 : uno::Sequence< sal_Int32 > aSequenceMapping;
702 :
703 : DataSourceHelper::detectRangeSegmentation(
704 : uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ),
705 0 : aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
706 :
707 0 : if( !bHasCategories && rDataOperator.setsCategories( bUseColumns ) )
708 0 : bHasCategories = true;
709 :
710 0 : aRangeString = "all";
711 : uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments(
712 0 : aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) );
713 :
714 :
715 : // /-- locked controllers
716 0 : ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ));
717 :
718 : // create and attach new data source
719 0 : switchToInternalDataProvider();
720 0 : rDataOperator.apply(m_xDataAccess);
721 0 : uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
722 : OSL_ASSERT( xDataProvider.is() );
723 0 : if( !xDataProvider.is() )
724 : return;
725 0 : uno::Reference< chart2::data::XDataSource > xSource( xDataProvider->createDataSource( aArguments ) );
726 :
727 0 : uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram() );
728 0 : if( xDia.is() )
729 0 : xDia->setDiagramData( xSource, aArguments );
730 :
731 : //correct stacking mode
732 0 : 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 0 : ::com::sun::star::chart::ChartDataChangeType_ALL, 0, 0, 0, 0 );
746 0 : 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 3 : } // namespace chart
768 :
769 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|