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