xref: /AOO41X/main/chart2/source/controller/dialogs/DataBrowserModel.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_chart2.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "DataBrowserModel.hxx"
32*cdf0e10cSrcweir #include "DialogModel.hxx"
33*cdf0e10cSrcweir #include "ChartModelHelper.hxx"
34*cdf0e10cSrcweir #include "DiagramHelper.hxx"
35*cdf0e10cSrcweir #include "DataSeriesHelper.hxx"
36*cdf0e10cSrcweir #include "PropertyHelper.hxx"
37*cdf0e10cSrcweir #include "ControllerLockGuard.hxx"
38*cdf0e10cSrcweir #include "macros.hxx"
39*cdf0e10cSrcweir #include "StatisticsHelper.hxx"
40*cdf0e10cSrcweir #include "ContainerHelper.hxx"
41*cdf0e10cSrcweir #include "ChartTypeHelper.hxx"
42*cdf0e10cSrcweir #include "chartview/ExplicitValueProvider.hxx"
43*cdf0e10cSrcweir #include "ExplicitCategoriesProvider.hxx"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include <com/sun/star/container/XIndexReplace.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/chart2/XAxis.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/chart2/XInternalDataProvider.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/chart2/XChartTypeContainer.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/chart2/data/XDataSource.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/chart2/data/XDataSink.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/util/XModifiable.hpp>
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir #include <rtl/math.hxx>
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir #include <algorithm>
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
63*cdf0e10cSrcweir #include <cstdio>
64*cdf0e10cSrcweir #endif
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir using namespace ::com::sun::star;
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
69*cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
70*cdf0e10cSrcweir using ::rtl::OUString;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir namespace
73*cdf0e10cSrcweir {
74*cdf0e10cSrcweir OUString lcl_getRole(
75*cdf0e10cSrcweir     const Reference< chart2::data::XDataSequence > & xSeq )
76*cdf0e10cSrcweir {
77*cdf0e10cSrcweir     OUString aResult;
78*cdf0e10cSrcweir     Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
79*cdf0e10cSrcweir     if( xProp.is())
80*cdf0e10cSrcweir     {
81*cdf0e10cSrcweir         try
82*cdf0e10cSrcweir         {
83*cdf0e10cSrcweir             xProp->getPropertyValue( C2U("Role")) >>= aResult;
84*cdf0e10cSrcweir         }
85*cdf0e10cSrcweir         catch( const uno::Exception & ex )
86*cdf0e10cSrcweir         {
87*cdf0e10cSrcweir             ASSERT_EXCEPTION( ex );
88*cdf0e10cSrcweir         }
89*cdf0e10cSrcweir     }
90*cdf0e10cSrcweir     return aResult;
91*cdf0e10cSrcweir }
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir OUString lcl_getRole(
95*cdf0e10cSrcweir     const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
96*cdf0e10cSrcweir {
97*cdf0e10cSrcweir     OUString aResult;
98*cdf0e10cSrcweir     if( xLSeq.is())
99*cdf0e10cSrcweir         aResult = lcl_getRole( xLSeq->getValues());
100*cdf0e10cSrcweir     return aResult;
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir OUString lcl_getUIRoleName(
104*cdf0e10cSrcweir     const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
105*cdf0e10cSrcweir {
106*cdf0e10cSrcweir     OUString aResult( lcl_getRole( xLSeq ));
107*cdf0e10cSrcweir     if( aResult.getLength())
108*cdf0e10cSrcweir         aResult = ::chart::DialogModel::ConvertRoleFromInternalToUI( aResult );
109*cdf0e10cSrcweir     return aResult;
110*cdf0e10cSrcweir }
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir void lcl_copyDataSequenceProperties(
113*cdf0e10cSrcweir     const Reference< chart2::data::XDataSequence > & xOldSequence,
114*cdf0e10cSrcweir     const Reference< chart2::data::XDataSequence > & xNewSequence )
115*cdf0e10cSrcweir {
116*cdf0e10cSrcweir     Reference< beans::XPropertySet > xOldSeqProp( xOldSequence, uno::UNO_QUERY );
117*cdf0e10cSrcweir     Reference< beans::XPropertySet > xNewSeqProp( xNewSequence, uno::UNO_QUERY );
118*cdf0e10cSrcweir     comphelper::copyProperties( xOldSeqProp, xNewSeqProp );
119*cdf0e10cSrcweir }
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir bool lcl_SequenceOfSeriesIsShared(
122*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries,
123*cdf0e10cSrcweir     const Reference< chart2::data::XDataSequence > & xValues )
124*cdf0e10cSrcweir {
125*cdf0e10cSrcweir     bool bResult = false;
126*cdf0e10cSrcweir     if( !xValues.is())
127*cdf0e10cSrcweir         return bResult;
128*cdf0e10cSrcweir     try
129*cdf0e10cSrcweir     {
130*cdf0e10cSrcweir         OUString aValuesRole( lcl_getRole( xValues ));
131*cdf0e10cSrcweir         OUString aValuesRep( xValues->getSourceRangeRepresentation());
132*cdf0e10cSrcweir         Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
133*cdf0e10cSrcweir         Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSeq( xSource->getDataSequences());
134*cdf0e10cSrcweir         for( sal_Int32 i=0; i<aLSeq.getLength(); ++i )
135*cdf0e10cSrcweir             if( aLSeq[i].is() &&
136*cdf0e10cSrcweir                 lcl_getRole( aLSeq[i] ).equals( aValuesRole ))
137*cdf0e10cSrcweir             {
138*cdf0e10cSrcweir                 // getValues().is(), because lcl_getRole checked that already
139*cdf0e10cSrcweir                 bResult = (aValuesRep == aLSeq[i]->getValues()->getSourceRangeRepresentation());
140*cdf0e10cSrcweir                 // assumption: a role appears only once in a series
141*cdf0e10cSrcweir                 break;
142*cdf0e10cSrcweir             }
143*cdf0e10cSrcweir     }
144*cdf0e10cSrcweir     catch( const uno::Exception & ex )
145*cdf0e10cSrcweir     {
146*cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
147*cdf0e10cSrcweir     }
148*cdf0e10cSrcweir     return bResult;
149*cdf0e10cSrcweir }
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir typedef ::std::vector< Reference< chart2::data::XLabeledDataSequence > > lcl_tSharedSeqVec;
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir lcl_tSharedSeqVec lcl_getSharedSequences( const Sequence< Reference< chart2::XDataSeries > > & rSeries )
154*cdf0e10cSrcweir {
155*cdf0e10cSrcweir     // @todo: if only some series share a sequence, those have to be duplicated
156*cdf0e10cSrcweir     // and made unshared for all series
157*cdf0e10cSrcweir     lcl_tSharedSeqVec aResult;
158*cdf0e10cSrcweir     // if we have only one series, we don't want any shared sequences
159*cdf0e10cSrcweir     if( rSeries.getLength() <= 1 )
160*cdf0e10cSrcweir         return aResult;
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir     Reference< chart2::data::XDataSource > xSource( rSeries[0], uno::UNO_QUERY );
163*cdf0e10cSrcweir     Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSeq( xSource->getDataSequences());
164*cdf0e10cSrcweir     for( sal_Int32 nIdx=0; nIdx<aLSeq.getLength(); ++nIdx )
165*cdf0e10cSrcweir     {
166*cdf0e10cSrcweir         Reference< chart2::data::XDataSequence > xValues( aLSeq[nIdx]->getValues());
167*cdf0e10cSrcweir         bool bShared = true;
168*cdf0e10cSrcweir         for( sal_Int32 nSeriesIdx=1; nSeriesIdx<rSeries.getLength(); ++nSeriesIdx )
169*cdf0e10cSrcweir         {
170*cdf0e10cSrcweir             bShared = lcl_SequenceOfSeriesIsShared( rSeries[nSeriesIdx], xValues );
171*cdf0e10cSrcweir             if( !bShared )
172*cdf0e10cSrcweir                 break;
173*cdf0e10cSrcweir         }
174*cdf0e10cSrcweir         if( bShared )
175*cdf0e10cSrcweir             aResult.push_back( aLSeq[nIdx] );
176*cdf0e10cSrcweir     }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir     return aResult;
179*cdf0e10cSrcweir }
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir sal_Int32 lcl_getValuesRepresentationIndex(
182*cdf0e10cSrcweir     const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
183*cdf0e10cSrcweir {
184*cdf0e10cSrcweir     sal_Int32 nResult = -1;
185*cdf0e10cSrcweir     if( xLSeq.is())
186*cdf0e10cSrcweir     {
187*cdf0e10cSrcweir         Reference< chart2::data::XDataSequence > xSeq( xLSeq->getValues());
188*cdf0e10cSrcweir         if( xSeq.is())
189*cdf0e10cSrcweir         {
190*cdf0e10cSrcweir             OUString aRep( xSeq->getSourceRangeRepresentation());
191*cdf0e10cSrcweir             nResult = aRep.toInt32();
192*cdf0e10cSrcweir         }
193*cdf0e10cSrcweir     }
194*cdf0e10cSrcweir     return nResult;
195*cdf0e10cSrcweir }
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir struct lcl_RepresentationsOfLSeqMatch : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
198*cdf0e10cSrcweir {
199*cdf0e10cSrcweir     lcl_RepresentationsOfLSeqMatch( const Reference< chart2::data::XLabeledDataSequence > & xLSeq ) :
200*cdf0e10cSrcweir             m_aValuesRep( xLSeq.is() ?
201*cdf0e10cSrcweir                           (xLSeq->getValues().is() ? xLSeq->getValues()->getSourceRangeRepresentation() : OUString())
202*cdf0e10cSrcweir                           : OUString() )
203*cdf0e10cSrcweir     {}
204*cdf0e10cSrcweir     bool operator() ( const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
205*cdf0e10cSrcweir     {
206*cdf0e10cSrcweir         return (xLSeq.is() &&
207*cdf0e10cSrcweir                 xLSeq->getValues().is() &&
208*cdf0e10cSrcweir                 (xLSeq->getValues()->getSourceRangeRepresentation() == m_aValuesRep ));
209*cdf0e10cSrcweir     }
210*cdf0e10cSrcweir private:
211*cdf0e10cSrcweir     OUString m_aValuesRep;
212*cdf0e10cSrcweir };
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir struct lcl_RolesOfLSeqMatch : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
215*cdf0e10cSrcweir {
216*cdf0e10cSrcweir     lcl_RolesOfLSeqMatch( const Reference< chart2::data::XLabeledDataSequence > & xLSeq ) :
217*cdf0e10cSrcweir             m_aRole( lcl_getRole( xLSeq ))
218*cdf0e10cSrcweir     {}
219*cdf0e10cSrcweir     bool operator() ( const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
220*cdf0e10cSrcweir     {
221*cdf0e10cSrcweir         return lcl_getRole( xLSeq ).equals( m_aRole );
222*cdf0e10cSrcweir     }
223*cdf0e10cSrcweir private:
224*cdf0e10cSrcweir     OUString m_aRole;
225*cdf0e10cSrcweir };
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir bool lcl_ShowCategories( const Reference< chart2::XDiagram > & /* xDiagram */ )
228*cdf0e10cSrcweir {
229*cdf0e10cSrcweir     // show categories for all charts
230*cdf0e10cSrcweir     return true;
231*cdf0e10cSrcweir //     return DiagramHelper::isCategoryDiagram( xDiagram );
232*cdf0e10cSrcweir }
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir bool lcl_ShowCategoriesAsDataLabel( const Reference< chart2::XDiagram > & xDiagram )
235*cdf0e10cSrcweir {
236*cdf0e10cSrcweir     return ! ::chart::DiagramHelper::isCategoryDiagram( xDiagram );
237*cdf0e10cSrcweir }
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir } // anonymous namespace
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir namespace chart
242*cdf0e10cSrcweir {
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir struct DataBrowserModel::tDataColumn
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir     ::com::sun::star::uno::Reference<
248*cdf0e10cSrcweir             ::com::sun::star::chart2::XDataSeries >                m_xDataSeries;
249*cdf0e10cSrcweir     sal_Int32                                                  m_nIndexInDataSeries;
250*cdf0e10cSrcweir     ::rtl::OUString                                            m_aUIRoleName;
251*cdf0e10cSrcweir     ::com::sun::star::uno::Reference<
252*cdf0e10cSrcweir             ::com::sun::star::chart2::data::XLabeledDataSequence > m_xLabeledDataSequence;
253*cdf0e10cSrcweir     eCellType                                                  m_eCellType;
254*cdf0e10cSrcweir     sal_Int32                                                  m_nNumberFormatKey;
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir     // default CTOR
257*cdf0e10cSrcweir     tDataColumn() : m_nIndexInDataSeries( -1 ), m_eCellType( TEXT ), m_nNumberFormatKey( 0 ) {}
258*cdf0e10cSrcweir     // "full" CTOR
259*cdf0e10cSrcweir     tDataColumn(
260*cdf0e10cSrcweir         const ::com::sun::star::uno::Reference<
261*cdf0e10cSrcweir         ::com::sun::star::chart2::XDataSeries > & xDataSeries,
262*cdf0e10cSrcweir         sal_Int32 nIndexInDataSeries,
263*cdf0e10cSrcweir         ::rtl::OUString aUIRoleName,
264*cdf0e10cSrcweir         ::com::sun::star::uno::Reference<
265*cdf0e10cSrcweir         ::com::sun::star::chart2::data::XLabeledDataSequence >  xLabeledDataSequence,
266*cdf0e10cSrcweir         eCellType aCellType,
267*cdf0e10cSrcweir         sal_Int32 nNumberFormatKey ) :
268*cdf0e10cSrcweir             m_xDataSeries( xDataSeries ),
269*cdf0e10cSrcweir             m_nIndexInDataSeries( nIndexInDataSeries ),
270*cdf0e10cSrcweir             m_aUIRoleName( aUIRoleName ),
271*cdf0e10cSrcweir             m_xLabeledDataSequence( xLabeledDataSequence ),
272*cdf0e10cSrcweir             m_eCellType( aCellType ),
273*cdf0e10cSrcweir             m_nNumberFormatKey( nNumberFormatKey )
274*cdf0e10cSrcweir     {}
275*cdf0e10cSrcweir };
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir struct DataBrowserModel::implColumnLess : public ::std::binary_function<
278*cdf0e10cSrcweir         DataBrowserModel::tDataColumn, DataBrowserModel::tDataColumn, bool >
279*cdf0e10cSrcweir {
280*cdf0e10cSrcweir     bool operator() ( const first_argument_type & rLeft, const second_argument_type & rRight )
281*cdf0e10cSrcweir     {
282*cdf0e10cSrcweir         if( rLeft.m_xLabeledDataSequence.is() && rRight.m_xLabeledDataSequence.is())
283*cdf0e10cSrcweir         {
284*cdf0e10cSrcweir             return DialogModel::GetRoleIndexForSorting( lcl_getRole( rLeft.m_xLabeledDataSequence )) <
285*cdf0e10cSrcweir                 DialogModel::GetRoleIndexForSorting( lcl_getRole( rRight.m_xLabeledDataSequence ));
286*cdf0e10cSrcweir         }
287*cdf0e10cSrcweir         return true;
288*cdf0e10cSrcweir     }
289*cdf0e10cSrcweir };
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir DataBrowserModel::DataBrowserModel(
292*cdf0e10cSrcweir     const Reference< chart2::XChartDocument > & xChartDoc,
293*cdf0e10cSrcweir     const Reference< uno::XComponentContext > & xContext ) :
294*cdf0e10cSrcweir         m_xChartDocument( xChartDoc ),
295*cdf0e10cSrcweir         m_xContext( xContext ),
296*cdf0e10cSrcweir         m_apDialogModel( new DialogModel( xChartDoc, xContext ))
297*cdf0e10cSrcweir {
298*cdf0e10cSrcweir     updateFromModel();
299*cdf0e10cSrcweir }
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir DataBrowserModel::~DataBrowserModel()
302*cdf0e10cSrcweir {}
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir namespace
305*cdf0e10cSrcweir {
306*cdf0e10cSrcweir struct lcl_DataSeriesOfHeaderMatches : public ::std::unary_function< ::chart::DataBrowserModel::tDataHeader, bool >
307*cdf0e10cSrcweir {
308*cdf0e10cSrcweir     lcl_DataSeriesOfHeaderMatches(
309*cdf0e10cSrcweir         const Reference< chart2::XDataSeries > & xSeriesToCompareWith ) :
310*cdf0e10cSrcweir             m_xSeries( xSeriesToCompareWith )
311*cdf0e10cSrcweir     {}
312*cdf0e10cSrcweir     bool operator() ( const ::chart::DataBrowserModel::tDataHeader & rHeader )
313*cdf0e10cSrcweir     {
314*cdf0e10cSrcweir         return (m_xSeries == rHeader.m_xDataSeries);
315*cdf0e10cSrcweir     }
316*cdf0e10cSrcweir private:
317*cdf0e10cSrcweir     Reference< chart2::XDataSeries  > m_xSeries;
318*cdf0e10cSrcweir };
319*cdf0e10cSrcweir }
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex )
322*cdf0e10cSrcweir {
323*cdf0e10cSrcweir     OSL_ASSERT( m_apDialogModel.get());
324*cdf0e10cSrcweir     Reference< chart2::XInternalDataProvider > xDataProvider(
325*cdf0e10cSrcweir         m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
326*cdf0e10cSrcweir     if( xDataProvider.is())
327*cdf0e10cSrcweir     {
328*cdf0e10cSrcweir         if( isCategoriesColumn(nAfterColumnIndex) )
329*cdf0e10cSrcweir             nAfterColumnIndex = getCategoryColumnCount()-1;
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir         sal_Int32 nStartCol = 0;
332*cdf0e10cSrcweir         Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartDocument ));
333*cdf0e10cSrcweir         Reference< chart2::XChartType > xChartType;
334*cdf0e10cSrcweir         Reference< chart2::XDataSeries > xSeries;
335*cdf0e10cSrcweir         if( static_cast< tDataColumnVector::size_type >( nAfterColumnIndex ) <= m_aColumns.size())
336*cdf0e10cSrcweir             xSeries.set( m_aColumns[nAfterColumnIndex].m_xDataSeries );
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir         sal_Int32 nSeriesNumberFormat = 0;
339*cdf0e10cSrcweir         if( xSeries.is())
340*cdf0e10cSrcweir         {
341*cdf0e10cSrcweir             xChartType.set( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ));
342*cdf0e10cSrcweir             tDataHeaderVector::const_iterator aIt(
343*cdf0e10cSrcweir                 ::std::find_if( m_aHeaders.begin(), m_aHeaders.end(),
344*cdf0e10cSrcweir                                 lcl_DataSeriesOfHeaderMatches( xSeries )));
345*cdf0e10cSrcweir             if( aIt != m_aHeaders.end())
346*cdf0e10cSrcweir                 nStartCol = aIt->m_nEndColumn;
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir             Reference< beans::XPropertySet > xSeriesProps( xSeries, uno::UNO_QUERY );
349*cdf0e10cSrcweir             if( xSeriesProps.is() )
350*cdf0e10cSrcweir                 xSeriesProps->getPropertyValue( C2U( "NumberFormat" )) >>= nSeriesNumberFormat;
351*cdf0e10cSrcweir         }
352*cdf0e10cSrcweir         else
353*cdf0e10cSrcweir         {
354*cdf0e10cSrcweir             xChartType.set( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ));
355*cdf0e10cSrcweir             nStartCol = nAfterColumnIndex;
356*cdf0e10cSrcweir         }
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir         if( xChartType.is())
359*cdf0e10cSrcweir         {
360*cdf0e10cSrcweir             sal_Int32 nOffset = 0;
361*cdf0e10cSrcweir             if( xDiagram.is() && lcl_ShowCategories( xDiagram ))
362*cdf0e10cSrcweir                 nOffset=getCategoryColumnCount();
363*cdf0e10cSrcweir             // get shared sequences of current series
364*cdf0e10cSrcweir             Reference< chart2::XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY );
365*cdf0e10cSrcweir             lcl_tSharedSeqVec aSharedSequences;
366*cdf0e10cSrcweir             if( xSeriesCnt.is())
367*cdf0e10cSrcweir                 aSharedSequences = lcl_getSharedSequences( xSeriesCnt->getDataSeries());
368*cdf0e10cSrcweir             Reference< chart2::XDataSeries > xNewSeries(
369*cdf0e10cSrcweir                 m_apDialogModel->insertSeriesAfter( xSeries, xChartType, true /* bCreateDataCachedSequences */ ));
370*cdf0e10cSrcweir             if( xNewSeries.is())
371*cdf0e10cSrcweir             {
372*cdf0e10cSrcweir                 {
373*cdf0e10cSrcweir                     Reference< chart2::data::XDataSource > xSource( xNewSeries, uno::UNO_QUERY );
374*cdf0e10cSrcweir                     if( xSource.is())
375*cdf0e10cSrcweir                     {
376*cdf0e10cSrcweir                         Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSequences(
377*cdf0e10cSrcweir                             xSource->getDataSequences());
378*cdf0e10cSrcweir                         sal_Int32 nSeqIdx = 0;
379*cdf0e10cSrcweir                         sal_Int32 nSeqSize = aLSequences.getLength();
380*cdf0e10cSrcweir                         nStartCol -= (nOffset - 1);
381*cdf0e10cSrcweir                         for( sal_Int32 nIndex = nStartCol;
382*cdf0e10cSrcweir                              (nSeqIdx < nSeqSize);
383*cdf0e10cSrcweir                              ++nSeqIdx )
384*cdf0e10cSrcweir                         {
385*cdf0e10cSrcweir                             lcl_tSharedSeqVec::const_iterator aSharedIt(
386*cdf0e10cSrcweir                                 ::std::find_if( aSharedSequences.begin(), aSharedSequences.end(),
387*cdf0e10cSrcweir                                                 lcl_RolesOfLSeqMatch( aLSequences[nSeqIdx] )));
388*cdf0e10cSrcweir                             if( aSharedIt != aSharedSequences.end())
389*cdf0e10cSrcweir                             {
390*cdf0e10cSrcweir                                 aLSequences[nSeqIdx]->setValues( (*aSharedIt)->getValues());
391*cdf0e10cSrcweir                                 aLSequences[nSeqIdx]->setLabel( (*aSharedIt)->getLabel());
392*cdf0e10cSrcweir                             }
393*cdf0e10cSrcweir                             else
394*cdf0e10cSrcweir                             {
395*cdf0e10cSrcweir                                 xDataProvider->insertSequence( nIndex - 1 );
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir                                 // values
398*cdf0e10cSrcweir                                 Reference< chart2::data::XDataSequence > xNewSeq(
399*cdf0e10cSrcweir                                     xDataProvider->createDataSequenceByRangeRepresentation(
400*cdf0e10cSrcweir                                         OUString::valueOf( nIndex )));
401*cdf0e10cSrcweir                                 lcl_copyDataSequenceProperties(
402*cdf0e10cSrcweir                                     aLSequences[nSeqIdx]->getValues(), xNewSeq );
403*cdf0e10cSrcweir                                 aLSequences[nSeqIdx]->setValues( xNewSeq );
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir                                 // labels
406*cdf0e10cSrcweir                                 Reference< chart2::data::XDataSequence > xNewLabelSeq(
407*cdf0e10cSrcweir                                     xDataProvider->createDataSequenceByRangeRepresentation(
408*cdf0e10cSrcweir                                         OUString( RTL_CONSTASCII_USTRINGPARAM( "label " )) +
409*cdf0e10cSrcweir                                         OUString::valueOf( nIndex )));
410*cdf0e10cSrcweir                                 lcl_copyDataSequenceProperties(
411*cdf0e10cSrcweir                                     aLSequences[nSeqIdx]->getLabel(), xNewLabelSeq );
412*cdf0e10cSrcweir                                 aLSequences[nSeqIdx]->setLabel( xNewLabelSeq );
413*cdf0e10cSrcweir                                 ++nIndex;
414*cdf0e10cSrcweir                             }
415*cdf0e10cSrcweir                         }
416*cdf0e10cSrcweir                     }
417*cdf0e10cSrcweir                 }
418*cdf0e10cSrcweir                 if( nSeriesNumberFormat != 0 )
419*cdf0e10cSrcweir                 {
420*cdf0e10cSrcweir                     //give the new series the same number format as the former series especially for bubble charts thus the bubble size values can be edited with same format immidiately
421*cdf0e10cSrcweir                     Reference< beans::XPropertySet > xNewSeriesProps( xNewSeries, uno::UNO_QUERY );
422*cdf0e10cSrcweir                     if( xNewSeriesProps.is() )
423*cdf0e10cSrcweir                         xNewSeriesProps->setPropertyValue( C2U( "NumberFormat" ), uno::makeAny( nSeriesNumberFormat ) );
424*cdf0e10cSrcweir                 }
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir                 updateFromModel();
427*cdf0e10cSrcweir             }
428*cdf0e10cSrcweir         }
429*cdf0e10cSrcweir     }
430*cdf0e10cSrcweir }
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir void DataBrowserModel::insertComplexCategoryLevel( sal_Int32 nAfterColumnIndex )
433*cdf0e10cSrcweir {
434*cdf0e10cSrcweir     //create a new text column for complex categories
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir     OSL_ASSERT( m_apDialogModel.get());
437*cdf0e10cSrcweir     Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
438*cdf0e10cSrcweir     if( xDataProvider.is() )
439*cdf0e10cSrcweir     {
440*cdf0e10cSrcweir         if( !isCategoriesColumn(nAfterColumnIndex) )
441*cdf0e10cSrcweir             nAfterColumnIndex = getCategoryColumnCount()-1;
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir         if(nAfterColumnIndex<0)
444*cdf0e10cSrcweir         {
445*cdf0e10cSrcweir             OSL_ENSURE( false, "wrong index for category level insertion" );
446*cdf0e10cSrcweir             return;
447*cdf0e10cSrcweir         }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir         m_apDialogModel->startControllerLockTimer();
450*cdf0e10cSrcweir         ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
451*cdf0e10cSrcweir         xDataProvider->insertComplexCategoryLevel( nAfterColumnIndex+1 );
452*cdf0e10cSrcweir         updateFromModel();
453*cdf0e10cSrcweir     }
454*cdf0e10cSrcweir }
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir void DataBrowserModel::removeDataSeriesOrComplexCategoryLevel( sal_Int32 nAtColumnIndex )
457*cdf0e10cSrcweir {
458*cdf0e10cSrcweir     OSL_ASSERT( m_apDialogModel.get());
459*cdf0e10cSrcweir     if( static_cast< tDataColumnVector::size_type >( nAtColumnIndex ) < m_aColumns.size())
460*cdf0e10cSrcweir     {
461*cdf0e10cSrcweir         Reference< chart2::XDataSeries > xSeries( m_aColumns[nAtColumnIndex].m_xDataSeries );
462*cdf0e10cSrcweir         if( xSeries.is())
463*cdf0e10cSrcweir         {
464*cdf0e10cSrcweir             m_apDialogModel->deleteSeries(
465*cdf0e10cSrcweir                 xSeries, getHeaderForSeries( xSeries ).m_xChartType );
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir             //delete sequences from internal data provider that are not used anymore
468*cdf0e10cSrcweir             //but do not delete sequences that are still in use by the remaining series
469*cdf0e10cSrcweir             Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
470*cdf0e10cSrcweir             Reference< chart2::data::XDataSource > xSourceOfDeletedSeries( xSeries, uno::UNO_QUERY );
471*cdf0e10cSrcweir             if( xDataProvider.is() && xSourceOfDeletedSeries.is())
472*cdf0e10cSrcweir             {
473*cdf0e10cSrcweir                 ::std::vector< sal_Int32 > aSequenceIndexesToDelete;
474*cdf0e10cSrcweir                 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequencesOfDeletedSeries( xSourceOfDeletedSeries->getDataSequences() );
475*cdf0e10cSrcweir                 Reference< chart2::XDataSeriesContainer > xSeriesCnt( getHeaderForSeries( xSeries ).m_xChartType, uno::UNO_QUERY );
476*cdf0e10cSrcweir                 if( xSeriesCnt.is())
477*cdf0e10cSrcweir                 {
478*cdf0e10cSrcweir                     Reference< chart2::data::XDataSource > xRemainingDataSource( DataSeriesHelper::getDataSource( xSeriesCnt->getDataSeries() ) );
479*cdf0e10cSrcweir                     if( xRemainingDataSource.is() )
480*cdf0e10cSrcweir                     {
481*cdf0e10cSrcweir                         ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aRemainingSeq( ContainerHelper::SequenceToVector( xRemainingDataSource->getDataSequences() ) );
482*cdf0e10cSrcweir                         for( sal_Int32 i=0; i<aSequencesOfDeletedSeries.getLength(); ++i )
483*cdf0e10cSrcweir                         {
484*cdf0e10cSrcweir                             ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aHitIt(
485*cdf0e10cSrcweir                                 ::std::find_if( aRemainingSeq.begin(), aRemainingSeq.end(),
486*cdf0e10cSrcweir                                     lcl_RepresentationsOfLSeqMatch( aSequencesOfDeletedSeries[i] )));
487*cdf0e10cSrcweir                             // if not used by the remaining series this sequence can be deleted
488*cdf0e10cSrcweir                             if( aHitIt == aRemainingSeq.end() )
489*cdf0e10cSrcweir                                 aSequenceIndexesToDelete.push_back( lcl_getValuesRepresentationIndex( aSequencesOfDeletedSeries[i] ) );
490*cdf0e10cSrcweir                         }
491*cdf0e10cSrcweir                     }
492*cdf0e10cSrcweir                 }
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir                 // delete unnecessary sequences of the internal data
495*cdf0e10cSrcweir                 // iterate using greatest index first, so that deletion does not
496*cdf0e10cSrcweir                 // shift other sequences that will be deleted later
497*cdf0e10cSrcweir                 ::std::sort( aSequenceIndexesToDelete.begin(), aSequenceIndexesToDelete.end());
498*cdf0e10cSrcweir                 for( ::std::vector< sal_Int32 >::reverse_iterator aIt(
499*cdf0e10cSrcweir                          aSequenceIndexesToDelete.rbegin()); aIt != aSequenceIndexesToDelete.rend(); ++aIt )
500*cdf0e10cSrcweir                 {
501*cdf0e10cSrcweir                     if( *aIt != -1 )
502*cdf0e10cSrcweir                         xDataProvider->deleteSequence( *aIt );
503*cdf0e10cSrcweir                 }
504*cdf0e10cSrcweir             }
505*cdf0e10cSrcweir             updateFromModel();
506*cdf0e10cSrcweir         }
507*cdf0e10cSrcweir         else
508*cdf0e10cSrcweir         {
509*cdf0e10cSrcweir             //delete a category column if there is more than one level (in case of a single column we do not get here)
510*cdf0e10cSrcweir             OSL_ENSURE(nAtColumnIndex>0, "wrong index for categories deletion" );
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir             Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
513*cdf0e10cSrcweir             if( xDataProvider.is() )
514*cdf0e10cSrcweir             {
515*cdf0e10cSrcweir                 m_apDialogModel->startControllerLockTimer();
516*cdf0e10cSrcweir                 ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
517*cdf0e10cSrcweir                 xDataProvider->deleteComplexCategoryLevel( nAtColumnIndex );
518*cdf0e10cSrcweir                 updateFromModel();
519*cdf0e10cSrcweir             }
520*cdf0e10cSrcweir         }
521*cdf0e10cSrcweir     }
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir void DataBrowserModel::swapDataSeries( sal_Int32 nFirstColumnIndex )
525*cdf0e10cSrcweir {
526*cdf0e10cSrcweir     OSL_ASSERT( m_apDialogModel.get());
527*cdf0e10cSrcweir     if( static_cast< tDataColumnVector::size_type >( nFirstColumnIndex ) < m_aColumns.size() - 1 )
528*cdf0e10cSrcweir     {
529*cdf0e10cSrcweir         Reference< chart2::XDataSeries > xSeries( m_aColumns[nFirstColumnIndex].m_xDataSeries );
530*cdf0e10cSrcweir         if( xSeries.is())
531*cdf0e10cSrcweir         {
532*cdf0e10cSrcweir             m_apDialogModel->moveSeries( xSeries, DialogModel::MOVE_DOWN );
533*cdf0e10cSrcweir             updateFromModel();
534*cdf0e10cSrcweir         }
535*cdf0e10cSrcweir     }
536*cdf0e10cSrcweir }
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir void DataBrowserModel::swapDataPointForAllSeries( sal_Int32 nFirstIndex )
539*cdf0e10cSrcweir {
540*cdf0e10cSrcweir     OSL_ASSERT( m_apDialogModel.get());
541*cdf0e10cSrcweir     Reference< chart2::XInternalDataProvider > xDataProvider(
542*cdf0e10cSrcweir         m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
543*cdf0e10cSrcweir     // lockControllers
544*cdf0e10cSrcweir     ControllerLockGuard aGuard( m_apDialogModel->getChartModel());
545*cdf0e10cSrcweir     if( xDataProvider.is())
546*cdf0e10cSrcweir         xDataProvider->swapDataPointWithNextOneForAllSequences( nFirstIndex );
547*cdf0e10cSrcweir     // unlockControllers
548*cdf0e10cSrcweir }
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir void DataBrowserModel::insertDataPointForAllSeries( sal_Int32 nAfterIndex )
551*cdf0e10cSrcweir {
552*cdf0e10cSrcweir     Reference< chart2::XInternalDataProvider > xDataProvider(
553*cdf0e10cSrcweir         m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
554*cdf0e10cSrcweir     // lockControllers
555*cdf0e10cSrcweir     ControllerLockGuard aGuard( m_apDialogModel->getChartModel());
556*cdf0e10cSrcweir     if( xDataProvider.is())
557*cdf0e10cSrcweir         xDataProvider->insertDataPointForAllSequences( nAfterIndex );
558*cdf0e10cSrcweir     // unlockControllers
559*cdf0e10cSrcweir }
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir void DataBrowserModel::removeDataPointForAllSeries( sal_Int32 nAtIndex )
562*cdf0e10cSrcweir {
563*cdf0e10cSrcweir     Reference< chart2::XInternalDataProvider > xDataProvider(
564*cdf0e10cSrcweir         m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
565*cdf0e10cSrcweir     // lockControllers
566*cdf0e10cSrcweir     ControllerLockGuard aGuard( m_apDialogModel->getChartModel());
567*cdf0e10cSrcweir     if( xDataProvider.is())
568*cdf0e10cSrcweir         xDataProvider->deleteDataPointForAllSequences( nAtIndex );
569*cdf0e10cSrcweir     // unlockControllers
570*cdf0e10cSrcweir }
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir DataBrowserModel::tDataHeader DataBrowserModel::getHeaderForSeries(
573*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xSeries ) const
574*cdf0e10cSrcweir {
575*cdf0e10cSrcweir     for( tDataHeaderVector::const_iterator aIt( m_aHeaders.begin());
576*cdf0e10cSrcweir          aIt != m_aHeaders.end(); ++aIt )
577*cdf0e10cSrcweir     {
578*cdf0e10cSrcweir         if( aIt->m_xDataSeries == xSeries )
579*cdf0e10cSrcweir             return (*aIt);
580*cdf0e10cSrcweir     }
581*cdf0e10cSrcweir     return tDataHeader();
582*cdf0e10cSrcweir }
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir Reference< chart2::XDataSeries >
585*cdf0e10cSrcweir     DataBrowserModel::getDataSeriesByColumn( sal_Int32 nColumn ) const
586*cdf0e10cSrcweir {
587*cdf0e10cSrcweir     tDataColumnVector::size_type nIndex( nColumn );
588*cdf0e10cSrcweir     if( nIndex < m_aColumns.size())
589*cdf0e10cSrcweir         return m_aColumns[nIndex].m_xDataSeries;
590*cdf0e10cSrcweir     return 0;
591*cdf0e10cSrcweir }
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir DataBrowserModel::eCellType DataBrowserModel::getCellType( sal_Int32 nAtColumn, sal_Int32 /* nAtRow */ ) const
594*cdf0e10cSrcweir {
595*cdf0e10cSrcweir     eCellType eResult = TEXT;
596*cdf0e10cSrcweir     tDataColumnVector::size_type nIndex( nAtColumn );
597*cdf0e10cSrcweir     if( nIndex < m_aColumns.size())
598*cdf0e10cSrcweir         eResult = m_aColumns[nIndex].m_eCellType;
599*cdf0e10cSrcweir     return eResult;
600*cdf0e10cSrcweir }
601*cdf0e10cSrcweir 
602*cdf0e10cSrcweir double DataBrowserModel::getCellNumber( sal_Int32 nAtColumn, sal_Int32 nAtRow )
603*cdf0e10cSrcweir {
604*cdf0e10cSrcweir     double fResult;
605*cdf0e10cSrcweir     ::rtl::math::setNan( & fResult );
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir     tDataColumnVector::size_type nIndex( nAtColumn );
608*cdf0e10cSrcweir     if( nIndex < m_aColumns.size() &&
609*cdf0e10cSrcweir         m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
610*cdf0e10cSrcweir     {
611*cdf0e10cSrcweir         Reference< chart2::data::XNumericalDataSequence > xData(
612*cdf0e10cSrcweir             m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY );
613*cdf0e10cSrcweir         if( xData.is())
614*cdf0e10cSrcweir         {
615*cdf0e10cSrcweir             Sequence< double > aValues( xData->getNumericalData());
616*cdf0e10cSrcweir             if( nAtRow < aValues.getLength())
617*cdf0e10cSrcweir                 fResult = aValues[nAtRow];
618*cdf0e10cSrcweir         }
619*cdf0e10cSrcweir     }
620*cdf0e10cSrcweir     return fResult;
621*cdf0e10cSrcweir }
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir uno::Any DataBrowserModel::getCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow )
624*cdf0e10cSrcweir {
625*cdf0e10cSrcweir     uno::Any aResult;
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir     tDataColumnVector::size_type nIndex( nAtColumn );
628*cdf0e10cSrcweir     if( nIndex < m_aColumns.size() &&
629*cdf0e10cSrcweir         m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
630*cdf0e10cSrcweir     {
631*cdf0e10cSrcweir         Reference< chart2::data::XDataSequence > xData(
632*cdf0e10cSrcweir             m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues() );
633*cdf0e10cSrcweir         if( xData.is() )
634*cdf0e10cSrcweir         {
635*cdf0e10cSrcweir             Sequence< uno::Any > aValues( xData->getData());
636*cdf0e10cSrcweir             if( nAtRow < aValues.getLength())
637*cdf0e10cSrcweir                 aResult = aValues[nAtRow];
638*cdf0e10cSrcweir         }
639*cdf0e10cSrcweir     }
640*cdf0e10cSrcweir     return aResult;
641*cdf0e10cSrcweir }
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir OUString DataBrowserModel::getCellText( sal_Int32 nAtColumn, sal_Int32 nAtRow )
644*cdf0e10cSrcweir {
645*cdf0e10cSrcweir     OUString aResult;
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir     tDataColumnVector::size_type nIndex( nAtColumn );
648*cdf0e10cSrcweir     if( nIndex < m_aColumns.size() &&
649*cdf0e10cSrcweir         m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
650*cdf0e10cSrcweir     {
651*cdf0e10cSrcweir         Reference< chart2::data::XTextualDataSequence > xData(
652*cdf0e10cSrcweir             m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY );
653*cdf0e10cSrcweir         if( xData.is())
654*cdf0e10cSrcweir         {
655*cdf0e10cSrcweir             Sequence< OUString > aValues( xData->getTextualData());
656*cdf0e10cSrcweir             if( nAtRow < aValues.getLength())
657*cdf0e10cSrcweir                 aResult = aValues[nAtRow];
658*cdf0e10cSrcweir         }
659*cdf0e10cSrcweir     }
660*cdf0e10cSrcweir     return aResult;
661*cdf0e10cSrcweir }
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir sal_uInt32 DataBrowserModel::getNumberFormatKey( sal_Int32 nAtColumn, sal_Int32 /* nAtRow */ )
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir     tDataColumnVector::size_type nIndex( nAtColumn );
666*cdf0e10cSrcweir     if( nIndex < m_aColumns.size())
667*cdf0e10cSrcweir         return m_aColumns[ nIndex ].m_nNumberFormatKey;
668*cdf0e10cSrcweir     return 0;
669*cdf0e10cSrcweir }
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir bool DataBrowserModel::setCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow, const uno::Any & rValue )
672*cdf0e10cSrcweir {
673*cdf0e10cSrcweir     bool bResult = false;
674*cdf0e10cSrcweir     tDataColumnVector::size_type nIndex( nAtColumn );
675*cdf0e10cSrcweir     if( nIndex < m_aColumns.size() &&
676*cdf0e10cSrcweir         m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
677*cdf0e10cSrcweir     {
678*cdf0e10cSrcweir         bResult = true;
679*cdf0e10cSrcweir         try
680*cdf0e10cSrcweir         {
681*cdf0e10cSrcweir             ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) );
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir             // label
684*cdf0e10cSrcweir             if( nAtRow == -1 )
685*cdf0e10cSrcweir             {
686*cdf0e10cSrcweir                 Reference< container::XIndexReplace > xIndexReplace(
687*cdf0e10cSrcweir                     m_aColumns[ nIndex ].m_xLabeledDataSequence->getLabel(), uno::UNO_QUERY_THROW );
688*cdf0e10cSrcweir                 xIndexReplace->replaceByIndex( 0, rValue );
689*cdf0e10cSrcweir             }
690*cdf0e10cSrcweir             else
691*cdf0e10cSrcweir             {
692*cdf0e10cSrcweir                 Reference< container::XIndexReplace > xIndexReplace(
693*cdf0e10cSrcweir                     m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY_THROW );
694*cdf0e10cSrcweir                 xIndexReplace->replaceByIndex( nAtRow, rValue );
695*cdf0e10cSrcweir             }
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir             m_apDialogModel->startControllerLockTimer();
698*cdf0e10cSrcweir             //notify change directly to the model (this is necessary here as sequences for complex categories not known directly to the chart model so they do not notify their changes) (for complex categories see issue #i82971#)
699*cdf0e10cSrcweir             Reference< util::XModifiable > xModifiable( m_xChartDocument, uno::UNO_QUERY );
700*cdf0e10cSrcweir             if( xModifiable.is() )
701*cdf0e10cSrcweir                 xModifiable->setModified(true);
702*cdf0e10cSrcweir         }
703*cdf0e10cSrcweir         catch( const uno::Exception & ex )
704*cdf0e10cSrcweir         {
705*cdf0e10cSrcweir             (void)(ex);
706*cdf0e10cSrcweir             bResult = false;
707*cdf0e10cSrcweir         }
708*cdf0e10cSrcweir     }
709*cdf0e10cSrcweir     return bResult;
710*cdf0e10cSrcweir }
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir bool DataBrowserModel::setCellNumber( sal_Int32 nAtColumn, sal_Int32 nAtRow, double fValue )
713*cdf0e10cSrcweir {
714*cdf0e10cSrcweir     return (getCellType( nAtColumn, nAtRow ) == NUMBER) &&
715*cdf0e10cSrcweir         setCellAny( nAtColumn, nAtRow, uno::makeAny( fValue ));
716*cdf0e10cSrcweir }
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir bool DataBrowserModel::setCellText( sal_Int32 nAtColumn, sal_Int32 nAtRow, const ::rtl::OUString & rText )
719*cdf0e10cSrcweir {
720*cdf0e10cSrcweir     return (getCellType( nAtColumn, nAtRow ) == TEXT) &&
721*cdf0e10cSrcweir         setCellAny( nAtColumn, nAtRow, uno::makeAny( rText ));
722*cdf0e10cSrcweir }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir sal_Int32 DataBrowserModel::getColumnCount() const
725*cdf0e10cSrcweir {
726*cdf0e10cSrcweir     return static_cast< sal_Int32 >( m_aColumns.size());
727*cdf0e10cSrcweir }
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir sal_Int32 DataBrowserModel::getMaxRowCount() const
730*cdf0e10cSrcweir {
731*cdf0e10cSrcweir     sal_Int32 nResult = 0;
732*cdf0e10cSrcweir     tDataColumnVector::const_iterator aIt( m_aColumns.begin());
733*cdf0e10cSrcweir     for( ; aIt != m_aColumns.end(); ++aIt )
734*cdf0e10cSrcweir     {
735*cdf0e10cSrcweir         if( aIt->m_xLabeledDataSequence.is())
736*cdf0e10cSrcweir         {
737*cdf0e10cSrcweir             Reference< chart2::data::XDataSequence > xSeq(
738*cdf0e10cSrcweir                 aIt->m_xLabeledDataSequence->getValues());
739*cdf0e10cSrcweir             if( !xSeq.is())
740*cdf0e10cSrcweir                 continue;
741*cdf0e10cSrcweir             sal_Int32 nLength( xSeq->getData().getLength());
742*cdf0e10cSrcweir             if( nLength > nResult )
743*cdf0e10cSrcweir                 nResult = nLength;
744*cdf0e10cSrcweir         }
745*cdf0e10cSrcweir     }
746*cdf0e10cSrcweir 
747*cdf0e10cSrcweir     return nResult;
748*cdf0e10cSrcweir }
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir OUString DataBrowserModel::getRoleOfColumn( sal_Int32 nColumnIndex ) const
751*cdf0e10cSrcweir {
752*cdf0e10cSrcweir     if( nColumnIndex != -1 &&
753*cdf0e10cSrcweir         static_cast< sal_uInt32 >( nColumnIndex ) < m_aColumns.size())
754*cdf0e10cSrcweir         return m_aColumns[ nColumnIndex ].m_aUIRoleName;
755*cdf0e10cSrcweir     return OUString();
756*cdf0e10cSrcweir }
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir bool DataBrowserModel::isCategoriesColumn( sal_Int32 nColumnIndex ) const
759*cdf0e10cSrcweir {
760*cdf0e10cSrcweir     bool bIsCategories = false;
761*cdf0e10cSrcweir     if( nColumnIndex>=0 && nColumnIndex<static_cast< sal_Int32 >(m_aColumns.size()) )
762*cdf0e10cSrcweir         bIsCategories = !m_aColumns[ nColumnIndex ].m_xDataSeries.is();
763*cdf0e10cSrcweir     return bIsCategories;
764*cdf0e10cSrcweir }
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir sal_Int32 DataBrowserModel::getCategoryColumnCount()
767*cdf0e10cSrcweir {
768*cdf0e10cSrcweir     sal_Int32 nLastTextColumnIndex = -1;
769*cdf0e10cSrcweir     tDataColumnVector::const_iterator aIt = m_aColumns.begin();
770*cdf0e10cSrcweir     for( ; aIt != m_aColumns.end(); ++aIt )
771*cdf0e10cSrcweir     {
772*cdf0e10cSrcweir         if( !aIt->m_xDataSeries.is() )
773*cdf0e10cSrcweir             nLastTextColumnIndex++;
774*cdf0e10cSrcweir         else
775*cdf0e10cSrcweir             break;
776*cdf0e10cSrcweir     }
777*cdf0e10cSrcweir     return nLastTextColumnIndex+1;
778*cdf0e10cSrcweir }
779*cdf0e10cSrcweir 
780*cdf0e10cSrcweir const DataBrowserModel::tDataHeaderVector& DataBrowserModel::getDataHeaders() const
781*cdf0e10cSrcweir {
782*cdf0e10cSrcweir     return m_aHeaders;
783*cdf0e10cSrcweir }
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir void DataBrowserModel::updateFromModel()
786*cdf0e10cSrcweir {
787*cdf0e10cSrcweir     if( !m_xChartDocument.is())
788*cdf0e10cSrcweir         return;
789*cdf0e10cSrcweir     m_aColumns.clear();
790*cdf0e10cSrcweir     m_aHeaders.clear();
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir     Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartDocument ));
793*cdf0e10cSrcweir     if( !xDiagram.is())
794*cdf0e10cSrcweir         return;
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir     // set template at DialogModel
797*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xFact( m_xChartDocument->getChartTypeManager(), uno::UNO_QUERY );
798*cdf0e10cSrcweir     DiagramHelper::tTemplateWithServiceName aTemplateAndService =
799*cdf0e10cSrcweir         DiagramHelper::getTemplateForDiagram( xDiagram, xFact );
800*cdf0e10cSrcweir     if( aTemplateAndService.first.is())
801*cdf0e10cSrcweir         m_apDialogModel->setTemplate( aTemplateAndService.first );
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir     sal_Int32 nHeaderStart = 0;
804*cdf0e10cSrcweir     sal_Int32 nHeaderEnd   = 0;
805*cdf0e10cSrcweir     if( lcl_ShowCategories( xDiagram ))
806*cdf0e10cSrcweir     {
807*cdf0e10cSrcweir         Reference< frame::XModel > xChartModel( m_xChartDocument, uno::UNO_QUERY );
808*cdf0e10cSrcweir         ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel );
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir         const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() );
811*cdf0e10cSrcweir         sal_Int32 nLevelCount = rSplitCategoriesList.getLength();
812*cdf0e10cSrcweir         for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
813*cdf0e10cSrcweir         {
814*cdf0e10cSrcweir             Reference< chart2::data::XLabeledDataSequence > xCategories( rSplitCategoriesList[nL] );
815*cdf0e10cSrcweir             if( !xCategories.is() )
816*cdf0e10cSrcweir                 continue;
817*cdf0e10cSrcweir 
818*cdf0e10cSrcweir             tDataColumn aCategories;
819*cdf0e10cSrcweir             aCategories.m_xLabeledDataSequence.set( xCategories );
820*cdf0e10cSrcweir             if( lcl_ShowCategoriesAsDataLabel( xDiagram ))
821*cdf0e10cSrcweir                 aCategories.m_aUIRoleName = DialogModel::GetRoleDataLabel();
822*cdf0e10cSrcweir             else
823*cdf0e10cSrcweir                 aCategories.m_aUIRoleName = lcl_getUIRoleName( xCategories );
824*cdf0e10cSrcweir             aCategories.m_eCellType = TEXTORDATE;
825*cdf0e10cSrcweir             m_aColumns.push_back( aCategories );
826*cdf0e10cSrcweir             ++nHeaderStart;
827*cdf0e10cSrcweir         }
828*cdf0e10cSrcweir     }
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir     Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
831*cdf0e10cSrcweir     if( !xCooSysCnt.is())
832*cdf0e10cSrcweir         return;
833*cdf0e10cSrcweir     Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
834*cdf0e10cSrcweir     for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
835*cdf0e10cSrcweir     {
836*cdf0e10cSrcweir         Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
837*cdf0e10cSrcweir         Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
838*cdf0e10cSrcweir         sal_Int32 nXAxisNumberFormat = DataSeriesHelper::getNumberFormatKeyFromAxis( 0, aCooSysSeq[nCooSysIdx], 0, 0 );
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir         for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
841*cdf0e10cSrcweir         {
842*cdf0e10cSrcweir             Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nCTIdx], uno::UNO_QUERY );
843*cdf0e10cSrcweir             if( xSeriesCnt.is())
844*cdf0e10cSrcweir             {
845*cdf0e10cSrcweir                 rtl::OUString aRoleForDataLabelNumberFormat = ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( aChartTypes[nCTIdx] );
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir                 Sequence< Reference< chart2::XDataSeries > > aSeries( xSeriesCnt->getDataSeries());
848*cdf0e10cSrcweir                 lcl_tSharedSeqVec aSharedSequences( lcl_getSharedSequences( aSeries ));
849*cdf0e10cSrcweir                 for( lcl_tSharedSeqVec::const_iterator aIt( aSharedSequences.begin());
850*cdf0e10cSrcweir                      aIt != aSharedSequences.end(); ++aIt )
851*cdf0e10cSrcweir                 {
852*cdf0e10cSrcweir                     tDataColumn aSharedSequence;
853*cdf0e10cSrcweir                     aSharedSequence.m_xLabeledDataSequence = *aIt;
854*cdf0e10cSrcweir                     aSharedSequence.m_aUIRoleName = lcl_getUIRoleName( *aIt );
855*cdf0e10cSrcweir                     aSharedSequence.m_eCellType = NUMBER;
856*cdf0e10cSrcweir                     // as the sequences are shared it should be ok to take the first series
857*cdf0e10cSrcweir                     // @todo: dimension index 0 for x-values used here. This is just a guess.
858*cdf0e10cSrcweir                     // Also, the axis index is 0, as there is usually only one x-axis
859*cdf0e10cSrcweir                     aSharedSequence.m_nNumberFormatKey = nXAxisNumberFormat;
860*cdf0e10cSrcweir                     m_aColumns.push_back( aSharedSequence );
861*cdf0e10cSrcweir                     ++nHeaderStart;
862*cdf0e10cSrcweir                 }
863*cdf0e10cSrcweir                 for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeries.getLength(); ++nSeriesIdx )
864*cdf0e10cSrcweir                 {
865*cdf0e10cSrcweir                     tDataColumnVector::size_type nStartColIndex = m_aColumns.size();
866*cdf0e10cSrcweir                     Reference< chart2::XDataSeries > xSeries( aSeries[nSeriesIdx] );
867*cdf0e10cSrcweir                     Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
868*cdf0e10cSrcweir                     if( xSource.is())
869*cdf0e10cSrcweir                     {
870*cdf0e10cSrcweir                         Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSeqs( xSource->getDataSequences());
871*cdf0e10cSrcweir                         if( aLSeqs.getLength() == 0 )
872*cdf0e10cSrcweir                             continue;
873*cdf0e10cSrcweir                         nHeaderEnd = nHeaderStart;
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir                         // @todo: dimension index 1 for y-values used here. This is just a guess
876*cdf0e10cSrcweir                         sal_Int32 nYAxisNumberFormatKey =
877*cdf0e10cSrcweir                             DataSeriesHelper::getNumberFormatKeyFromAxis(
878*cdf0e10cSrcweir                                 aSeries[nSeriesIdx], aCooSysSeq[nCooSysIdx], 1 );
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir                         sal_Int32 nSeqIdx=0;
881*cdf0e10cSrcweir                         for( ; nSeqIdx<aLSeqs.getLength(); ++nSeqIdx )
882*cdf0e10cSrcweir                         {
883*cdf0e10cSrcweir                             sal_Int32 nSequenceNumberFormatKey = nYAxisNumberFormatKey;
884*cdf0e10cSrcweir                             OUString aRole = lcl_getRole( aLSeqs[nSeqIdx] );
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir                             if( aRole.equals( aRoleForDataLabelNumberFormat ) )
887*cdf0e10cSrcweir                             {
888*cdf0e10cSrcweir                                 nSequenceNumberFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
889*cdf0e10cSrcweir                                     Reference< beans::XPropertySet >( xSeries, uno::UNO_QUERY ), xSeries, -1, xDiagram );
890*cdf0e10cSrcweir                             }
891*cdf0e10cSrcweir                             else if( aRole.equals( C2U( "values-x" ) ) )
892*cdf0e10cSrcweir                                 nSequenceNumberFormatKey = nXAxisNumberFormat;
893*cdf0e10cSrcweir 
894*cdf0e10cSrcweir                             if( ::std::find_if( aSharedSequences.begin(), aSharedSequences.end(),
895*cdf0e10cSrcweir                                              lcl_RepresentationsOfLSeqMatch( aLSeqs[nSeqIdx] )) == aSharedSequences.end())
896*cdf0e10cSrcweir                             {
897*cdf0e10cSrcweir                                 // no shared sequence
898*cdf0e10cSrcweir                                 m_aColumns.push_back(
899*cdf0e10cSrcweir                                     tDataColumn(
900*cdf0e10cSrcweir                                         aSeries[nSeriesIdx],
901*cdf0e10cSrcweir                                         nSeqIdx,
902*cdf0e10cSrcweir                                         lcl_getUIRoleName( aLSeqs[nSeqIdx] ),
903*cdf0e10cSrcweir                                         aLSeqs[nSeqIdx],
904*cdf0e10cSrcweir                                         NUMBER,
905*cdf0e10cSrcweir                                         nSequenceNumberFormatKey ));
906*cdf0e10cSrcweir                                 ++nHeaderEnd;
907*cdf0e10cSrcweir                             }
908*cdf0e10cSrcweir                             // else skip
909*cdf0e10cSrcweir                         }
910*cdf0e10cSrcweir                         bool bSwapXAndYAxis = false;
911*cdf0e10cSrcweir                         try
912*cdf0e10cSrcweir                         {
913*cdf0e10cSrcweir                             Reference< beans::XPropertySet > xProp( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY );
914*cdf0e10cSrcweir                             xProp->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("SwapXAndYAxis"))) >>= bSwapXAndYAxis;
915*cdf0e10cSrcweir                         }
916*cdf0e10cSrcweir                         catch( const beans::UnknownPropertyException & ex )
917*cdf0e10cSrcweir                         {
918*cdf0e10cSrcweir                             (void)ex;
919*cdf0e10cSrcweir                         }
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir                         // add ranges for error bars if present for a series
922*cdf0e10cSrcweir                         if( StatisticsHelper::usesErrorBarRanges( aSeries[nSeriesIdx], /* bYError = */ true ))
923*cdf0e10cSrcweir                             addErrorBarRanges( aSeries[nSeriesIdx], nYAxisNumberFormatKey, nSeqIdx, nHeaderEnd );
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir                         m_aHeaders.push_back(
926*cdf0e10cSrcweir                             tDataHeader(
927*cdf0e10cSrcweir                                 aSeries[nSeriesIdx],
928*cdf0e10cSrcweir                                 aChartTypes[nCTIdx],
929*cdf0e10cSrcweir                                 bSwapXAndYAxis,
930*cdf0e10cSrcweir                                 nHeaderStart,
931*cdf0e10cSrcweir                                 nHeaderEnd - 1 ));
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir                         nHeaderStart = nHeaderEnd;
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir                         ::std::sort( m_aColumns.begin() + nStartColIndex, m_aColumns.end(), implColumnLess() );
936*cdf0e10cSrcweir                     }
937*cdf0e10cSrcweir                 }
938*cdf0e10cSrcweir             }
939*cdf0e10cSrcweir         }
940*cdf0e10cSrcweir     }
941*cdf0e10cSrcweir }
942*cdf0e10cSrcweir 
943*cdf0e10cSrcweir void DataBrowserModel::addErrorBarRanges(
944*cdf0e10cSrcweir     const Reference< chart2::XDataSeries > & xDataSeries,
945*cdf0e10cSrcweir     sal_Int32 nNumberFormatKey,
946*cdf0e10cSrcweir     sal_Int32 & rInOutSequenceIndex,
947*cdf0e10cSrcweir     sal_Int32 & rInOutHeaderEnd )
948*cdf0e10cSrcweir {
949*cdf0e10cSrcweir     try
950*cdf0e10cSrcweir     {
951*cdf0e10cSrcweir         ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aSequences;
952*cdf0e10cSrcweir 
953*cdf0e10cSrcweir         // x error bars
954*cdf0e10cSrcweir         // ------------
955*cdf0e10cSrcweir         Reference< chart2::data::XDataSource > xErrorSource(
956*cdf0e10cSrcweir             StatisticsHelper::getErrorBars( xDataSeries, /* bYError = */ false ), uno::UNO_QUERY );
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir         // positive x error bars
959*cdf0e10cSrcweir         Reference< chart2::data::XLabeledDataSequence > xErrorLSequence(
960*cdf0e10cSrcweir             StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
961*cdf0e10cSrcweir                 xErrorSource,
962*cdf0e10cSrcweir                 /* bPositiveValue = */ true,
963*cdf0e10cSrcweir                 /* bYError = */ false ));
964*cdf0e10cSrcweir         if( xErrorLSequence.is())
965*cdf0e10cSrcweir             aSequences.push_back( xErrorLSequence );
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir         // negative x error bars
968*cdf0e10cSrcweir         xErrorLSequence.set(
969*cdf0e10cSrcweir             StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
970*cdf0e10cSrcweir                 xErrorSource,
971*cdf0e10cSrcweir                 /* bPositiveValue = */ false,
972*cdf0e10cSrcweir                 /* bYError = */ false ));
973*cdf0e10cSrcweir         if( xErrorLSequence.is())
974*cdf0e10cSrcweir             aSequences.push_back( xErrorLSequence );
975*cdf0e10cSrcweir 
976*cdf0e10cSrcweir         // y error bars
977*cdf0e10cSrcweir         // ------------
978*cdf0e10cSrcweir         xErrorSource.set(
979*cdf0e10cSrcweir             StatisticsHelper::getErrorBars( xDataSeries, /* bYError = */ true ), uno::UNO_QUERY );
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir         // positive y error bars
982*cdf0e10cSrcweir         xErrorLSequence.set(
983*cdf0e10cSrcweir             StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
984*cdf0e10cSrcweir                 xErrorSource,
985*cdf0e10cSrcweir                 /* bPositiveValue = */ true,
986*cdf0e10cSrcweir                 /* bYError = */ true ));
987*cdf0e10cSrcweir         if( xErrorLSequence.is())
988*cdf0e10cSrcweir             aSequences.push_back( xErrorLSequence );
989*cdf0e10cSrcweir 
990*cdf0e10cSrcweir         // negative y error bars
991*cdf0e10cSrcweir         xErrorLSequence.set(
992*cdf0e10cSrcweir             StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
993*cdf0e10cSrcweir                 xErrorSource,
994*cdf0e10cSrcweir                 /* bPositiveValue = */ false,
995*cdf0e10cSrcweir                 /* bYError = */ true ));
996*cdf0e10cSrcweir         if( xErrorLSequence.is())
997*cdf0e10cSrcweir             aSequences.push_back( xErrorLSequence );
998*cdf0e10cSrcweir 
999*cdf0e10cSrcweir 
1000*cdf0e10cSrcweir         for( ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aIt( aSequences.begin());
1001*cdf0e10cSrcweir              aIt != aSequences.end(); ++aIt )
1002*cdf0e10cSrcweir         {
1003*cdf0e10cSrcweir             m_aColumns.push_back(
1004*cdf0e10cSrcweir                 tDataColumn(
1005*cdf0e10cSrcweir                     xDataSeries,
1006*cdf0e10cSrcweir                     rInOutSequenceIndex,
1007*cdf0e10cSrcweir                     lcl_getUIRoleName( *aIt ),
1008*cdf0e10cSrcweir                     *aIt,
1009*cdf0e10cSrcweir                     NUMBER,
1010*cdf0e10cSrcweir                     nNumberFormatKey ));
1011*cdf0e10cSrcweir             ++rInOutSequenceIndex;
1012*cdf0e10cSrcweir             ++rInOutHeaderEnd;
1013*cdf0e10cSrcweir         }
1014*cdf0e10cSrcweir     }
1015*cdf0e10cSrcweir     catch( const uno::Exception & ex )
1016*cdf0e10cSrcweir     {
1017*cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
1018*cdf0e10cSrcweir     }
1019*cdf0e10cSrcweir }
1020*cdf0e10cSrcweir 
1021*cdf0e10cSrcweir } //  namespace chart
1022