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