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 "ExplicitCategoriesProvider.hxx"
32*cdf0e10cSrcweir #include "DiagramHelper.hxx"
33*cdf0e10cSrcweir #include "ChartTypeHelper.hxx"
34*cdf0e10cSrcweir #include "AxisHelper.hxx"
35*cdf0e10cSrcweir #include "CommonConverters.hxx"
36*cdf0e10cSrcweir #include "DataSourceHelper.hxx"
37*cdf0e10cSrcweir #include "ChartModelHelper.hxx"
38*cdf0e10cSrcweir #include "ContainerHelper.hxx"
39*cdf0e10cSrcweir #include "macros.hxx"
40*cdf0e10cSrcweir #include "NumberFormatterWrapper.hxx"
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <com/sun/star/chart2/AxisType.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir //.............................................................................
47*cdf0e10cSrcweir namespace chart
48*cdf0e10cSrcweir {
49*cdf0e10cSrcweir //.............................................................................
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir using namespace ::com::sun::star;
52*cdf0e10cSrcweir using namespace ::com::sun::star::chart2;
53*cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
54*cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
55*cdf0e10cSrcweir using ::rtl::OUString;
56*cdf0e10cSrcweir using ::std::vector;
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2::XCoordinateSystem >& xCooSysModel
60*cdf0e10cSrcweir                                                        , const uno::Reference< frame::XModel >& xChartModel )
61*cdf0e10cSrcweir     : m_bDirty(true)
62*cdf0e10cSrcweir     , m_xCooSysModel( xCooSysModel )
63*cdf0e10cSrcweir     , m_xChartModel( xChartModel )
64*cdf0e10cSrcweir     , m_xOriginalCategories()
65*cdf0e10cSrcweir     , m_bIsExplicitCategoriesInited(false)
66*cdf0e10cSrcweir     , m_bIsDateAxis(false)
67*cdf0e10cSrcweir     , m_bIsAutoDate(false)
68*cdf0e10cSrcweir {
69*cdf0e10cSrcweir     try
70*cdf0e10cSrcweir     {
71*cdf0e10cSrcweir         if( xCooSysModel.is() )
72*cdf0e10cSrcweir         {
73*cdf0e10cSrcweir             uno::Reference< XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
74*cdf0e10cSrcweir             if( xAxis.is() )
75*cdf0e10cSrcweir             {
76*cdf0e10cSrcweir                 ScaleData aScale( xAxis->getScaleData() );
77*cdf0e10cSrcweir                 m_xOriginalCategories = aScale.Categories;
78*cdf0e10cSrcweir                 m_bIsAutoDate = (aScale.AutoDateAxis && aScale.AxisType==chart2::AxisType::CATEGORY);
79*cdf0e10cSrcweir                 m_bIsDateAxis = (aScale.AxisType == chart2::AxisType::DATE || m_bIsAutoDate);
80*cdf0e10cSrcweir             }
81*cdf0e10cSrcweir         }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir         if( m_xOriginalCategories.is() )
84*cdf0e10cSrcweir         {
85*cdf0e10cSrcweir             Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
86*cdf0e10cSrcweir             if( xChartDoc.is() )
87*cdf0e10cSrcweir             {
88*cdf0e10cSrcweir                 uno::Reference< data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir                 OUString aCatgoriesRange( DataSourceHelper::getRangeFromValues( m_xOriginalCategories ) );
91*cdf0e10cSrcweir                 if( xDataProvider.is() && aCatgoriesRange.getLength() )
92*cdf0e10cSrcweir                 {
93*cdf0e10cSrcweir                     const bool bFirstCellAsLabel = false;
94*cdf0e10cSrcweir                     const bool bHasCategories = false;
95*cdf0e10cSrcweir                     const uno::Sequence< sal_Int32 > aSequenceMapping;
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir                     uno::Reference< data::XDataSource > xColumnCategoriesSource( xDataProvider->createDataSource(
98*cdf0e10cSrcweir                          DataSourceHelper::createArguments( aCatgoriesRange, aSequenceMapping, true /*bUseColumns*/
99*cdf0e10cSrcweir                             , bFirstCellAsLabel, bHasCategories ) ) );
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir                     uno::Reference< data::XDataSource > xRowCategoriesSource( xDataProvider->createDataSource(
102*cdf0e10cSrcweir                          DataSourceHelper::createArguments( aCatgoriesRange, aSequenceMapping, false /*bUseColumns*/
103*cdf0e10cSrcweir                             , bFirstCellAsLabel, bHasCategories ) ) );
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir                     if( xColumnCategoriesSource.is() &&  xRowCategoriesSource.is() )
106*cdf0e10cSrcweir                     {
107*cdf0e10cSrcweir                         Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences();
108*cdf0e10cSrcweir                         Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences();
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir                         sal_Int32 nColumnCount = aColumns.getLength();
111*cdf0e10cSrcweir                         sal_Int32 nRowCount = aRows.getLength();
112*cdf0e10cSrcweir                         if( nColumnCount>1 && nRowCount>1 )
113*cdf0e10cSrcweir                         {
114*cdf0e10cSrcweir                             //we have complex categories
115*cdf0e10cSrcweir                             //->split them in the direction of the first series
116*cdf0e10cSrcweir                             //detect whether the first series is a row or a column
117*cdf0e10cSrcweir                             bool bSeriesUsesColumns = true;
118*cdf0e10cSrcweir                             ::std::vector< Reference< XDataSeries > > aSeries( ChartModelHelper::getDataSeries( xChartModel ) );
119*cdf0e10cSrcweir                             if( !aSeries.empty() )
120*cdf0e10cSrcweir                             {
121*cdf0e10cSrcweir                                 uno::Reference< data::XDataSource > xSeriesSource( aSeries.front(), uno::UNO_QUERY );
122*cdf0e10cSrcweir                                 ::rtl::OUString aStringDummy;
123*cdf0e10cSrcweir                                 bool bDummy;
124*cdf0e10cSrcweir                                 uno::Sequence< sal_Int32 > aSeqDummy;
125*cdf0e10cSrcweir                                 DataSourceHelper::readArguments( xDataProvider->detectArguments( xSeriesSource),
126*cdf0e10cSrcweir                                                aStringDummy, aSeqDummy, bSeriesUsesColumns, bDummy, bDummy );
127*cdf0e10cSrcweir                             }
128*cdf0e10cSrcweir                             if( bSeriesUsesColumns )
129*cdf0e10cSrcweir                                 m_aSplitCategoriesList=aColumns;
130*cdf0e10cSrcweir                             else
131*cdf0e10cSrcweir                                 m_aSplitCategoriesList=aRows;
132*cdf0e10cSrcweir                         }
133*cdf0e10cSrcweir                     }
134*cdf0e10cSrcweir                 }
135*cdf0e10cSrcweir             }
136*cdf0e10cSrcweir             if( !m_aSplitCategoriesList.getLength() )
137*cdf0e10cSrcweir             {
138*cdf0e10cSrcweir                 m_aSplitCategoriesList.realloc(1);
139*cdf0e10cSrcweir                 m_aSplitCategoriesList[0]=m_xOriginalCategories;
140*cdf0e10cSrcweir             }
141*cdf0e10cSrcweir         }
142*cdf0e10cSrcweir     }
143*cdf0e10cSrcweir     catch( const uno::Exception & ex )
144*cdf0e10cSrcweir     {
145*cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
146*cdf0e10cSrcweir     }
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir ExplicitCategoriesProvider::~ExplicitCategoriesProvider()
150*cdf0e10cSrcweir {
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir Reference< chart2::data::XDataSequence > ExplicitCategoriesProvider::getOriginalCategories()
154*cdf0e10cSrcweir {
155*cdf0e10cSrcweir     if( m_xOriginalCategories.is() )
156*cdf0e10cSrcweir         return m_xOriginalCategories->getValues();
157*cdf0e10cSrcweir     return 0;
158*cdf0e10cSrcweir }
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir const Sequence< Reference< data::XLabeledDataSequence> >& ExplicitCategoriesProvider::getSplitCategoriesList()
161*cdf0e10cSrcweir {
162*cdf0e10cSrcweir     return m_aSplitCategoriesList;
163*cdf0e10cSrcweir }
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir bool ExplicitCategoriesProvider::hasComplexCategories() const
166*cdf0e10cSrcweir {
167*cdf0e10cSrcweir     return m_aSplitCategoriesList.getLength() > 1;
168*cdf0e10cSrcweir }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir sal_Int32 ExplicitCategoriesProvider::getCategoryLevelCount() const
171*cdf0e10cSrcweir {
172*cdf0e10cSrcweir     sal_Int32 nCount = m_aSplitCategoriesList.getLength();
173*cdf0e10cSrcweir     if(!nCount)
174*cdf0e10cSrcweir         nCount = 1;
175*cdf0e10cSrcweir     return nCount;
176*cdf0e10cSrcweir }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir std::vector<sal_Int32> lcl_getLimitingBorders( const std::vector< ComplexCategory >& rComplexCategories )
179*cdf0e10cSrcweir {
180*cdf0e10cSrcweir     std::vector<sal_Int32> aLimitingBorders;
181*cdf0e10cSrcweir     std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() );
182*cdf0e10cSrcweir     std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
183*cdf0e10cSrcweir     sal_Int32 nBorderIndex = 0; /*border below the index*/
184*cdf0e10cSrcweir     for( ; aIt != aEnd; ++aIt )
185*cdf0e10cSrcweir     {
186*cdf0e10cSrcweir         ComplexCategory aComplexCategory(*aIt);
187*cdf0e10cSrcweir         nBorderIndex += aComplexCategory.Count;
188*cdf0e10cSrcweir         aLimitingBorders.push_back(nBorderIndex);
189*cdf0e10cSrcweir     }
190*cdf0e10cSrcweir     return aLimitingBorders;
191*cdf0e10cSrcweir }
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir void ExplicitCategoriesProvider::convertCategoryAnysToText( uno::Sequence< rtl::OUString >& rOutTexts, const uno::Sequence< uno::Any >& rInAnys, Reference< frame::XModel > xChartModel )
194*cdf0e10cSrcweir {
195*cdf0e10cSrcweir     sal_Int32 nCount = rInAnys.getLength();
196*cdf0e10cSrcweir     if(!nCount)
197*cdf0e10cSrcweir         return;
198*cdf0e10cSrcweir     rOutTexts.realloc(nCount);
199*cdf0e10cSrcweir     Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY );
200*cdf0e10cSrcweir     Reference< util::XNumberFormats > xNumberFormats;
201*cdf0e10cSrcweir     if( xNumberFormatsSupplier.is() )
202*cdf0e10cSrcweir          xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir     sal_Int32 nAxisNumberFormat = 0;
205*cdf0e10cSrcweir     Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
206*cdf0e10cSrcweir     if( xCooSysModel.is() )
207*cdf0e10cSrcweir     {
208*cdf0e10cSrcweir         Reference< chart2::XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
209*cdf0e10cSrcweir         nAxisNumberFormat = AxisHelper::getExplicitNumberFormatKeyForAxis(
210*cdf0e10cSrcweir                   xAxis, xCooSysModel, xNumberFormatsSupplier, false );
211*cdf0e10cSrcweir     }
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir     sal_Int32 nLabelColor;
214*cdf0e10cSrcweir     bool bColorChanged = false;
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir     NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir     for(sal_Int32 nN=0;nN<nCount;nN++)
219*cdf0e10cSrcweir     {
220*cdf0e10cSrcweir         rtl::OUString aText;
221*cdf0e10cSrcweir         uno::Any aAny = rInAnys[nN];
222*cdf0e10cSrcweir         if( aAny.hasValue() )
223*cdf0e10cSrcweir         {
224*cdf0e10cSrcweir             double fDouble = 0;
225*cdf0e10cSrcweir             if( aAny>>=fDouble )
226*cdf0e10cSrcweir             {
227*cdf0e10cSrcweir                 if( !::rtl::math::isNan(fDouble) )
228*cdf0e10cSrcweir                     aText = aNumberFormatterWrapper.getFormattedString(
229*cdf0e10cSrcweir                         nAxisNumberFormat, fDouble, nLabelColor, bColorChanged );
230*cdf0e10cSrcweir             }
231*cdf0e10cSrcweir             else
232*cdf0e10cSrcweir             {
233*cdf0e10cSrcweir                 aAny>>=aText;
234*cdf0e10cSrcweir             }
235*cdf0e10cSrcweir         }
236*cdf0e10cSrcweir         rOutTexts[nN] = aText;
237*cdf0e10cSrcweir     }
238*cdf0e10cSrcweir }
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir SplitCategoriesProvider::~SplitCategoriesProvider()
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir class SplitCategoriesProvider_ForLabeledDataSequences : public SplitCategoriesProvider
245*cdf0e10cSrcweir {
246*cdf0e10cSrcweir public:
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir     explicit SplitCategoriesProvider_ForLabeledDataSequences(
249*cdf0e10cSrcweir         const ::com::sun::star::uno::Sequence<
250*cdf0e10cSrcweir             ::com::sun::star::uno::Reference<
251*cdf0e10cSrcweir                 ::com::sun::star::chart2::data::XLabeledDataSequence> >& rSplitCategoriesList
252*cdf0e10cSrcweir         , const Reference< frame::XModel >& xChartModel )
253*cdf0e10cSrcweir         : m_rSplitCategoriesList( rSplitCategoriesList )
254*cdf0e10cSrcweir         , m_xChartModel( xChartModel )
255*cdf0e10cSrcweir     {}
256*cdf0e10cSrcweir     virtual ~SplitCategoriesProvider_ForLabeledDataSequences()
257*cdf0e10cSrcweir     {}
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir     virtual sal_Int32 getLevelCount() const;
260*cdf0e10cSrcweir     virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const;
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir private:
263*cdf0e10cSrcweir     const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
264*cdf0e10cSrcweir         ::com::sun::star::chart2::data::XLabeledDataSequence> >& m_rSplitCategoriesList;
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir     Reference< frame::XModel > m_xChartModel;
267*cdf0e10cSrcweir };
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir sal_Int32 SplitCategoriesProvider_ForLabeledDataSequences::getLevelCount() const
270*cdf0e10cSrcweir {
271*cdf0e10cSrcweir     return m_rSplitCategoriesList.getLength();
272*cdf0e10cSrcweir }
273*cdf0e10cSrcweir uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForLabeledDataSequences::getStringsForLevel( sal_Int32 nLevel ) const
274*cdf0e10cSrcweir {
275*cdf0e10cSrcweir     uno::Sequence< rtl::OUString > aRet;
276*cdf0e10cSrcweir     Reference< data::XLabeledDataSequence > xLabeledDataSequence( m_rSplitCategoriesList[nLevel] );
277*cdf0e10cSrcweir     if( xLabeledDataSequence.is() )
278*cdf0e10cSrcweir     {
279*cdf0e10cSrcweir         uno::Reference< data::XDataSequence > xDataSequence( xLabeledDataSequence->getValues() );
280*cdf0e10cSrcweir         if( xDataSequence.is() )
281*cdf0e10cSrcweir             ExplicitCategoriesProvider::convertCategoryAnysToText( aRet, xDataSequence->getData(), m_xChartModel );
282*cdf0e10cSrcweir     }
283*cdf0e10cSrcweir     return aRet;
284*cdf0e10cSrcweir }
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(
287*cdf0e10cSrcweir     const uno::Sequence< rtl::OUString >& rStrings
288*cdf0e10cSrcweir     , const std::vector<sal_Int32>& rLimitingBorders, bool bCreateSingleCategories )
289*cdf0e10cSrcweir {
290*cdf0e10cSrcweir     std::vector< ComplexCategory > aResult;
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir     sal_Int32 nMaxCount = rStrings.getLength();
293*cdf0e10cSrcweir     OUString aPrevious;
294*cdf0e10cSrcweir     sal_Int32 nCurrentCount=0;
295*cdf0e10cSrcweir     for( sal_Int32 nN=0; nN<nMaxCount; nN++ )
296*cdf0e10cSrcweir     {
297*cdf0e10cSrcweir         OUString aCurrent = rStrings[nN];
298*cdf0e10cSrcweir         if( bCreateSingleCategories || ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
299*cdf0e10cSrcweir         {
300*cdf0e10cSrcweir             aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
301*cdf0e10cSrcweir             nCurrentCount=1;
302*cdf0e10cSrcweir             aPrevious = aCurrent;
303*cdf0e10cSrcweir         }
304*cdf0e10cSrcweir         else
305*cdf0e10cSrcweir         {
306*cdf0e10cSrcweir             if( aCurrent.getLength() && aPrevious != aCurrent )
307*cdf0e10cSrcweir             {
308*cdf0e10cSrcweir                 aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
309*cdf0e10cSrcweir                 nCurrentCount=1;
310*cdf0e10cSrcweir                 aPrevious = aCurrent;
311*cdf0e10cSrcweir             }
312*cdf0e10cSrcweir             else
313*cdf0e10cSrcweir                 nCurrentCount++;
314*cdf0e10cSrcweir         }
315*cdf0e10cSrcweir     }
316*cdf0e10cSrcweir     if( nCurrentCount )
317*cdf0e10cSrcweir         aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir     return aResult;
320*cdf0e10cSrcweir }
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir sal_Int32 lcl_getCategoryCount( std::vector< ComplexCategory >& rComplexCategories )
323*cdf0e10cSrcweir {
324*cdf0e10cSrcweir     sal_Int32 nCount = 0;
325*cdf0e10cSrcweir     std::vector< ComplexCategory >::iterator aIt( rComplexCategories.begin() );
326*cdf0e10cSrcweir     std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
327*cdf0e10cSrcweir     for( ; aIt != aEnd; ++aIt )
328*cdf0e10cSrcweir         nCount+=aIt->Count;
329*cdf0e10cSrcweir     return nCount;
330*cdf0e10cSrcweir }
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir Sequence< OUString > lcl_getExplicitSimpleCategories(
333*cdf0e10cSrcweir     const SplitCategoriesProvider& rSplitCategoriesProvider,
334*cdf0e10cSrcweir     ::std::vector< ::std::vector< ComplexCategory > >& rComplexCats )
335*cdf0e10cSrcweir {
336*cdf0e10cSrcweir     Sequence< OUString > aRet;
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir     rComplexCats.clear();
339*cdf0e10cSrcweir     sal_Int32 nLCount = rSplitCategoriesProvider.getLevelCount();
340*cdf0e10cSrcweir     for( sal_Int32 nL = 0; nL < nLCount; nL++ )
341*cdf0e10cSrcweir     {
342*cdf0e10cSrcweir         std::vector<sal_Int32> aLimitingBorders;
343*cdf0e10cSrcweir         if(nL>0)
344*cdf0e10cSrcweir             aLimitingBorders = lcl_getLimitingBorders( rComplexCats.back() );
345*cdf0e10cSrcweir         rComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector(
346*cdf0e10cSrcweir             rSplitCategoriesProvider.getStringsForLevel(nL), aLimitingBorders, nL==(nLCount-1) ) );
347*cdf0e10cSrcweir     }
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir     std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( rComplexCats.begin() );
350*cdf0e10cSrcweir     std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( rComplexCats.end() );
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir     //ensure that the category count is the same on each level
353*cdf0e10cSrcweir     sal_Int32 nMaxCategoryCount = 0;
354*cdf0e10cSrcweir     {
355*cdf0e10cSrcweir         for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
356*cdf0e10cSrcweir         {
357*cdf0e10cSrcweir             sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
358*cdf0e10cSrcweir             nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount );
359*cdf0e10cSrcweir         }
360*cdf0e10cSrcweir         for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
361*cdf0e10cSrcweir         {
362*cdf0e10cSrcweir             sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
363*cdf0e10cSrcweir             if( nCurrentCount< nMaxCategoryCount )
364*cdf0e10cSrcweir             {
365*cdf0e10cSrcweir                 ComplexCategory& rComplexCategory = aOuterIt->back();
366*cdf0e10cSrcweir                 rComplexCategory.Count += (nMaxCategoryCount-nCurrentCount);
367*cdf0e10cSrcweir             }
368*cdf0e10cSrcweir         }
369*cdf0e10cSrcweir     }
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir     //create a list with an element for every index
372*cdf0e10cSrcweir     std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex;
373*cdf0e10cSrcweir     for( aOuterIt=rComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
374*cdf0e10cSrcweir     {
375*cdf0e10cSrcweir         std::vector< ComplexCategory > aSingleLevel;
376*cdf0e10cSrcweir         std::vector< ComplexCategory >::iterator aIt( aOuterIt->begin() );
377*cdf0e10cSrcweir         std::vector< ComplexCategory >::const_iterator aEnd( aOuterIt->end() );
378*cdf0e10cSrcweir         for( ; aIt != aEnd; ++aIt )
379*cdf0e10cSrcweir         {
380*cdf0e10cSrcweir             ComplexCategory aComplexCategory( *aIt );
381*cdf0e10cSrcweir             sal_Int32 nCount = aComplexCategory.Count;
382*cdf0e10cSrcweir             while( nCount-- )
383*cdf0e10cSrcweir                 aSingleLevel.push_back(aComplexCategory);
384*cdf0e10cSrcweir         }
385*cdf0e10cSrcweir         aComplexCatsPerIndex.push_back( aSingleLevel );
386*cdf0e10cSrcweir     }
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir     if(nMaxCategoryCount)
389*cdf0e10cSrcweir     {
390*cdf0e10cSrcweir         aRet.realloc(nMaxCategoryCount);
391*cdf0e10cSrcweir         aOuterEnd = aComplexCatsPerIndex.end();
392*cdf0e10cSrcweir         OUString aSpace(C2U(" "));
393*cdf0e10cSrcweir         for(sal_Int32 nN=0; nN<nMaxCategoryCount; nN++)
394*cdf0e10cSrcweir         {
395*cdf0e10cSrcweir             OUString aText;
396*cdf0e10cSrcweir             for( aOuterIt=aComplexCatsPerIndex.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
397*cdf0e10cSrcweir             {
398*cdf0e10cSrcweir                 OUString aAddText = (*aOuterIt)[nN].Text;
399*cdf0e10cSrcweir                 if( aAddText.getLength() )
400*cdf0e10cSrcweir                 {
401*cdf0e10cSrcweir                     if(aText.getLength())
402*cdf0e10cSrcweir                         aText += aSpace;
403*cdf0e10cSrcweir                     aText += aAddText;
404*cdf0e10cSrcweir                 }
405*cdf0e10cSrcweir             }
406*cdf0e10cSrcweir             aRet[nN]=aText;
407*cdf0e10cSrcweir         }
408*cdf0e10cSrcweir     }
409*cdf0e10cSrcweir     return aRet;
410*cdf0e10cSrcweir }
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir Sequence< OUString > ExplicitCategoriesProvider::getExplicitSimpleCategories(
413*cdf0e10cSrcweir     const SplitCategoriesProvider& rSplitCategoriesProvider )
414*cdf0e10cSrcweir {
415*cdf0e10cSrcweir     vector< vector< ComplexCategory > > aComplexCats;
416*cdf0e10cSrcweir     return lcl_getExplicitSimpleCategories( rSplitCategoriesProvider, aComplexCats );
417*cdf0e10cSrcweir }
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir struct DatePlusIndexComparator
420*cdf0e10cSrcweir {
421*cdf0e10cSrcweir     inline bool operator() ( const DatePlusIndex& aFirst,
422*cdf0e10cSrcweir                              const DatePlusIndex& aSecond )
423*cdf0e10cSrcweir     {
424*cdf0e10cSrcweir         return ( aFirst.fValue < aSecond.fValue );
425*cdf0e10cSrcweir     }
426*cdf0e10cSrcweir };
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir bool lcl_fillDateCategories( const uno::Reference< data::XDataSequence >& xDataSequence, std::vector< DatePlusIndex >& rDateCategories, bool bIsAutoDate, Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier )
429*cdf0e10cSrcweir {
430*cdf0e10cSrcweir     bool bOnlyDatesFound = true;
431*cdf0e10cSrcweir     bool bAnyDataFound = false;
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir     if( xDataSequence.is() )
434*cdf0e10cSrcweir     {
435*cdf0e10cSrcweir         uno::Sequence< uno::Any > aValues = xDataSequence->getData();
436*cdf0e10cSrcweir         sal_Int32 nCount = aValues.getLength();
437*cdf0e10cSrcweir         rDateCategories.reserve(nCount);
438*cdf0e10cSrcweir         Reference< util::XNumberFormats > xNumberFormats;
439*cdf0e10cSrcweir         if( xNumberFormatsSupplier.is() )
440*cdf0e10cSrcweir              xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() );
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir         bool bOwnData = false;
443*cdf0e10cSrcweir         bool bOwnDataAnddAxisHasAnyFormat = false;
444*cdf0e10cSrcweir         bool bOwnDataAnddAxisHasDateFormat = false;
445*cdf0e10cSrcweir         Reference< chart2::XChartDocument > xChartDoc( xNumberFormatsSupplier, uno::UNO_QUERY );
446*cdf0e10cSrcweir         Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) );
447*cdf0e10cSrcweir         if( xChartDoc.is() && xCooSysModel.is() )
448*cdf0e10cSrcweir         {
449*cdf0e10cSrcweir             if( xChartDoc->hasInternalDataProvider() )
450*cdf0e10cSrcweir             {
451*cdf0e10cSrcweir                 bOwnData = true;
452*cdf0e10cSrcweir                 Reference< beans::XPropertySet > xAxisProps( xCooSysModel->getAxisByDimension(0,0), uno::UNO_QUERY );
453*cdf0e10cSrcweir                 sal_Int32 nAxisNumberFormat = 0;
454*cdf0e10cSrcweir                 if( xAxisProps.is() && (xAxisProps->getPropertyValue( C2U("NumberFormat") ) >>= nAxisNumberFormat) )
455*cdf0e10cSrcweir                 {
456*cdf0e10cSrcweir                     bOwnDataAnddAxisHasAnyFormat = true;
457*cdf0e10cSrcweir                     bOwnDataAnddAxisHasDateFormat = DiagramHelper::isDateNumberFormat( nAxisNumberFormat, xNumberFormats );
458*cdf0e10cSrcweir                 }
459*cdf0e10cSrcweir             }
460*cdf0e10cSrcweir         }
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir         for(sal_Int32 nN=0;nN<nCount;nN++)
463*cdf0e10cSrcweir         {
464*cdf0e10cSrcweir             bool bIsDate = false;
465*cdf0e10cSrcweir             if( bIsAutoDate )
466*cdf0e10cSrcweir             {
467*cdf0e10cSrcweir                 if( bOwnData )
468*cdf0e10cSrcweir                     bIsDate = bOwnDataAnddAxisHasAnyFormat ? bOwnDataAnddAxisHasDateFormat : true;
469*cdf0e10cSrcweir                 else
470*cdf0e10cSrcweir                     bIsDate = DiagramHelper::isDateNumberFormat( xDataSequence->getNumberFormatKeyByIndex( nN ), xNumberFormats );
471*cdf0e10cSrcweir             }
472*cdf0e10cSrcweir             else
473*cdf0e10cSrcweir                 bIsDate = true;
474*cdf0e10cSrcweir 
475*cdf0e10cSrcweir             bool bContainsEmptyString = false;
476*cdf0e10cSrcweir             bool bContainsNan = false;
477*cdf0e10cSrcweir             uno::Any aAny = aValues[nN];
478*cdf0e10cSrcweir             if( aAny.hasValue() )
479*cdf0e10cSrcweir             {
480*cdf0e10cSrcweir                 OUString aTest;
481*cdf0e10cSrcweir                 double fTest = 0;
482*cdf0e10cSrcweir                 if( (aAny>>=aTest) && !aTest.getLength() ) //empty String
483*cdf0e10cSrcweir                     bContainsEmptyString = true;
484*cdf0e10cSrcweir                 else if( (aAny>>=fTest) &&  ::rtl::math::isNan(fTest) )
485*cdf0e10cSrcweir                     bContainsNan = true;
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir                 if( !bContainsEmptyString && !bContainsNan )
488*cdf0e10cSrcweir                     bAnyDataFound = true;
489*cdf0e10cSrcweir             }
490*cdf0e10cSrcweir             DatePlusIndex aDatePlusIndex( 1.0, nN );
491*cdf0e10cSrcweir             if( bIsDate && (aAny >>= aDatePlusIndex.fValue) )
492*cdf0e10cSrcweir                 rDateCategories.push_back( aDatePlusIndex );
493*cdf0e10cSrcweir             else
494*cdf0e10cSrcweir             {
495*cdf0e10cSrcweir                 if( aAny.hasValue() && !bContainsEmptyString )//empty string does not count as non date value!
496*cdf0e10cSrcweir                     bOnlyDatesFound=false;
497*cdf0e10cSrcweir                 ::rtl::math::setNan( &aDatePlusIndex.fValue );
498*cdf0e10cSrcweir                 rDateCategories.push_back( aDatePlusIndex );
499*cdf0e10cSrcweir             }
500*cdf0e10cSrcweir         }
501*cdf0e10cSrcweir         ::std::sort( rDateCategories.begin(), rDateCategories.end(), DatePlusIndexComparator() );
502*cdf0e10cSrcweir     }
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir     return bAnyDataFound && bOnlyDatesFound;
505*cdf0e10cSrcweir }
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir void ExplicitCategoriesProvider::init()
508*cdf0e10cSrcweir {
509*cdf0e10cSrcweir     if( m_bDirty )
510*cdf0e10cSrcweir     {
511*cdf0e10cSrcweir         m_aComplexCats.clear();//not one per index
512*cdf0e10cSrcweir         m_aDateCategories.clear();
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir         if( m_xOriginalCategories.is() )
515*cdf0e10cSrcweir         {
516*cdf0e10cSrcweir             if( !hasComplexCategories() )
517*cdf0e10cSrcweir             {
518*cdf0e10cSrcweir                 if(m_bIsDateAxis)
519*cdf0e10cSrcweir                 {
520*cdf0e10cSrcweir                     if( ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ), 2, 0 ) )
521*cdf0e10cSrcweir                         m_bIsDateAxis = lcl_fillDateCategories( m_xOriginalCategories->getValues(), m_aDateCategories, m_bIsAutoDate, Reference< util::XNumberFormatsSupplier >( m_xChartModel.get(), uno::UNO_QUERY ) );
522*cdf0e10cSrcweir                     else
523*cdf0e10cSrcweir                         m_bIsDateAxis = false;
524*cdf0e10cSrcweir                 }
525*cdf0e10cSrcweir             }
526*cdf0e10cSrcweir             else
527*cdf0e10cSrcweir             {
528*cdf0e10cSrcweir                 m_bIsDateAxis = false;
529*cdf0e10cSrcweir             }
530*cdf0e10cSrcweir         }
531*cdf0e10cSrcweir         else
532*cdf0e10cSrcweir             m_bIsDateAxis=false;
533*cdf0e10cSrcweir         m_bDirty = false;
534*cdf0e10cSrcweir     }
535*cdf0e10cSrcweir }
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir Sequence< ::rtl::OUString > ExplicitCategoriesProvider::getSimpleCategories()
539*cdf0e10cSrcweir {
540*cdf0e10cSrcweir     if( !m_bIsExplicitCategoriesInited )
541*cdf0e10cSrcweir     {
542*cdf0e10cSrcweir         init();
543*cdf0e10cSrcweir         m_aExplicitCategories.realloc(0);
544*cdf0e10cSrcweir         if( m_xOriginalCategories.is() )
545*cdf0e10cSrcweir         {
546*cdf0e10cSrcweir             if( !hasComplexCategories() )
547*cdf0e10cSrcweir             {
548*cdf0e10cSrcweir                 uno::Reference< data::XDataSequence > xDataSequence( m_xOriginalCategories->getValues() );
549*cdf0e10cSrcweir                 if( xDataSequence.is() )
550*cdf0e10cSrcweir                     ExplicitCategoriesProvider::convertCategoryAnysToText( m_aExplicitCategories, xDataSequence->getData(), m_xChartModel );
551*cdf0e10cSrcweir             }
552*cdf0e10cSrcweir             else
553*cdf0e10cSrcweir             {
554*cdf0e10cSrcweir                 m_aExplicitCategories = lcl_getExplicitSimpleCategories(
555*cdf0e10cSrcweir                     SplitCategoriesProvider_ForLabeledDataSequences( m_aSplitCategoriesList, m_xChartModel ), m_aComplexCats );
556*cdf0e10cSrcweir             }
557*cdf0e10cSrcweir         }
558*cdf0e10cSrcweir         if(!m_aExplicitCategories.getLength())
559*cdf0e10cSrcweir             m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel );
560*cdf0e10cSrcweir         m_bIsExplicitCategoriesInited = true;
561*cdf0e10cSrcweir     }
562*cdf0e10cSrcweir     return m_aExplicitCategories;
563*cdf0e10cSrcweir }
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir std::vector< ComplexCategory >  ExplicitCategoriesProvider::getCategoriesByLevel( sal_Int32 nLevel )
566*cdf0e10cSrcweir {
567*cdf0e10cSrcweir     std::vector< ComplexCategory > aRet;
568*cdf0e10cSrcweir     init();
569*cdf0e10cSrcweir     sal_Int32 nMaxIndex = m_aComplexCats.size()-1;
570*cdf0e10cSrcweir     if( nLevel >= 0 && nLevel <= nMaxIndex  )
571*cdf0e10cSrcweir         aRet = m_aComplexCats[nMaxIndex-nLevel];
572*cdf0e10cSrcweir     return aRet;
573*cdf0e10cSrcweir }
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir OUString ExplicitCategoriesProvider::getCategoryByIndex(
576*cdf0e10cSrcweir           const Reference< XCoordinateSystem >& xCooSysModel
577*cdf0e10cSrcweir         , const uno::Reference< frame::XModel >& xChartModel
578*cdf0e10cSrcweir         , sal_Int32 nIndex )
579*cdf0e10cSrcweir {
580*cdf0e10cSrcweir     if( xCooSysModel.is())
581*cdf0e10cSrcweir     {
582*cdf0e10cSrcweir         ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSysModel, xChartModel );
583*cdf0e10cSrcweir         Sequence< OUString > aCategories( aExplicitCategoriesProvider.getSimpleCategories());
584*cdf0e10cSrcweir         if( nIndex < aCategories.getLength())
585*cdf0e10cSrcweir             return aCategories[ nIndex ];
586*cdf0e10cSrcweir     }
587*cdf0e10cSrcweir     return OUString();
588*cdf0e10cSrcweir }
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir bool ExplicitCategoriesProvider::isDateAxis()
591*cdf0e10cSrcweir {
592*cdf0e10cSrcweir     init();
593*cdf0e10cSrcweir     return m_bIsDateAxis;
594*cdf0e10cSrcweir }
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir const std::vector< DatePlusIndex >&  ExplicitCategoriesProvider::getDateCategories()
597*cdf0e10cSrcweir {
598*cdf0e10cSrcweir     init();
599*cdf0e10cSrcweir     return m_aDateCategories;
600*cdf0e10cSrcweir }
601*cdf0e10cSrcweir 
602*cdf0e10cSrcweir //.............................................................................
603*cdf0e10cSrcweir } //namespace chart
604*cdf0e10cSrcweir //.............................................................................
605