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