xref: /aoo41x/main/chart2/source/tools/AxisHelper.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 
31 #include "AxisHelper.hxx"
32 #include "DiagramHelper.hxx"
33 #include "ChartTypeHelper.hxx"
34 #include "macros.hxx"
35 #include "AxisIndexDefines.hxx"
36 #include "LineProperties.hxx"
37 #include "ContainerHelper.hxx"
38 #include "servicenames_coosystems.hxx"
39 #include "DataSeriesHelper.hxx"
40 #include "Scaling.hxx"
41 #include "ChartModelHelper.hxx"
42 #include "DataSourceHelper.hxx"
43 
44 #include <tools/debug.hxx>
45 #include <unotools/saveopt.hxx>
46 
47 #include <com/sun/star/chart/ChartAxisPosition.hpp>
48 
49 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
50 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
51 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
52 #include <com/sun/star/chart2/data/XDataSource.hpp>
53 
54 // header for class OUStringBuffer
55 #include <rtl/ustrbuf.hxx>
56 #include <rtl/math.hxx>
57 
58 #include <com/sun/star/util/XCloneable.hpp>
59 #include <com/sun/star/lang/XServiceName.hpp>
60 
61 #include <map>
62 
63 //.............................................................................
64 namespace chart
65 {
66 //.............................................................................
67 using namespace ::com::sun::star;
68 using namespace ::com::sun::star::chart2;
69 using ::com::sun::star::uno::Reference;
70 using ::com::sun::star::uno::Sequence;
71 
72 Reference< chart2::XScaling > AxisHelper::createLinearScaling()
73 {
74     return new LinearScaling( 1.0, 0.0 );
75 }
76 
77 Reference< chart2::XScaling > AxisHelper::createLogarithmicScaling( double fBase )
78 {
79     return new LogarithmicScaling( fBase );
80 }
81 
82 ScaleData AxisHelper::createDefaultScale()
83 {
84     ScaleData aScaleData;
85     aScaleData.AxisType = chart2::AxisType::REALNUMBER;
86     aScaleData.AutoDateAxis = true;
87     aScaleData.ShiftedCategoryPosition = false;//this is adapted in the view code currently
88     Sequence< SubIncrement > aSubIncrements(1);
89     aSubIncrements[0] = SubIncrement();
90     aScaleData.IncrementData.SubIncrements = aSubIncrements;
91     return aScaleData;
92 }
93 
94 void AxisHelper::removeExplicitScaling( ScaleData& rScaleData )
95 {
96     uno::Any aEmpty;
97     rScaleData.Minimum = rScaleData.Maximum = rScaleData.Origin = aEmpty;
98     rScaleData.Scaling = 0;
99     ScaleData aDefaultScale( createDefaultScale() );
100     rScaleData.IncrementData = aDefaultScale.IncrementData;
101     rScaleData.TimeIncrement = aDefaultScale.TimeIncrement;
102 }
103 
104 bool AxisHelper::isLogarithmic( const Reference< XScaling >& xScaling )
105 {
106     bool bReturn = false;
107     Reference< lang::XServiceName > xServiceName( xScaling, uno::UNO_QUERY );
108     bReturn =( xServiceName.is() && (xServiceName->getServiceName()).equals(
109               C2U( "com.sun.star.chart2.LogarithmicScaling" )));
110     return bReturn;
111 }
112 
113 chart2::ScaleData AxisHelper::getDateCheckedScale( const Reference< chart2::XAxis >& xAxis, const Reference< frame::XModel >& xChartModel )
114 {
115     DBG_ASSERT(xChartModel.is(),"missing chart model");
116     ScaleData aScale = xAxis->getScaleData();
117     Reference< chart2::XCoordinateSystem > xCooSys( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) );
118     if( aScale.AutoDateAxis && aScale.AxisType == AxisType::CATEGORY )
119     {
120         sal_Int32 nDimensionIndex=0; sal_Int32 nAxisIndex=0;
121         AxisHelper::getIndicesForAxis(xAxis, xCooSys, nDimensionIndex, nAxisIndex );
122         bool bChartTypeAllowsDateAxis = ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys, 0 ), 2, nDimensionIndex );
123         if( bChartTypeAllowsDateAxis )
124             aScale.AxisType = AxisType::DATE;
125     }
126     if( aScale.AxisType == AxisType::DATE )
127     {
128         ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys,xChartModel );
129         if( !aExplicitCategoriesProvider.isDateAxis() )
130             aScale.AxisType = AxisType::CATEGORY;
131     }
132     return aScale;
133 }
134 
135 void AxisHelper::checkDateAxis( chart2::ScaleData& rScale, ExplicitCategoriesProvider* pExplicitCategoriesProvider, bool bChartTypeAllowsDateAxis )
136 {
137     if( rScale.AutoDateAxis && rScale.AxisType == AxisType::CATEGORY && bChartTypeAllowsDateAxis )
138     {
139         rScale.AxisType = AxisType::DATE;
140         removeExplicitScaling( rScale );
141     }
142     if( rScale.AxisType == AxisType::DATE && (!pExplicitCategoriesProvider || !pExplicitCategoriesProvider->isDateAxis()) )
143     {
144         rScale.AxisType = AxisType::CATEGORY;
145         removeExplicitScaling( rScale );
146     }
147 }
148 
149 sal_Int32 AxisHelper::getExplicitNumberFormatKeyForAxis(
150                   const Reference< chart2::XAxis >& xAxis
151                 , const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem
152                 , const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier
153                 , bool bSearchForParallelAxisIfNothingIsFound )
154 {
155     sal_Int32 nNumberFormatKey(0);
156     bool bNumberFormatKeyFoundViaAttachedData = false;
157     sal_Int32 nAxisIndex = 0;
158     sal_Int32 nDimensionIndex = 1;
159     AxisHelper::getIndicesForAxis( xAxis, xCorrespondingCoordinateSystem, nDimensionIndex, nAxisIndex );
160     Reference< chart2::XChartDocument > xChartDoc( xNumberFormatsSupplier, uno::UNO_QUERY );
161 
162     Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
163     if( xProp.is() && !( xProp->getPropertyValue( C2U( "NumberFormat" ) ) >>= nNumberFormatKey ) )
164     {
165         bool bFormatSet = false;
166         //check wether we have a percent scale -> use percent format
167         if( xNumberFormatsSupplier.is() )
168         {
169             ScaleData aData = AxisHelper::getDateCheckedScale( xAxis, Reference< frame::XModel >( xNumberFormatsSupplier, uno::UNO_QUERY ) );
170             if( aData.AxisType==AxisType::PERCENT )
171             {
172                 sal_Int32 nPercentFormat = DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier );
173                 if( nPercentFormat != -1 )
174                 {
175                     nNumberFormatKey = nPercentFormat;
176                     bFormatSet = true;
177                 }
178             }
179             else if( aData.AxisType==AxisType::DATE )
180             {
181                 if( aData.Categories.is() )
182                 {
183                     Reference< data::XDataSequence > xSeq( aData.Categories->getValues());
184                     if( xSeq.is() && !( xChartDoc.is() && xChartDoc->hasInternalDataProvider()) )
185                         nNumberFormatKey = xSeq->getNumberFormatKeyByIndex( -1 );
186                     else
187                         nNumberFormatKey = DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier );
188                     bFormatSet = true;
189                 }
190             }
191             else if( xChartDoc.is() && xChartDoc->hasInternalDataProvider() && nDimensionIndex == 0 ) //maybe date axis
192             {
193                 Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram() );
194                 if( DiagramHelper::isSupportingDateAxis( xDiagram ) )
195                 {
196                     nNumberFormatKey = DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier );
197                 }
198                 else
199                 {
200                     Reference< data::XDataSource > xSource( DataSourceHelper::getUsedData( xChartDoc ) );
201                     if( xSource.is() )
202                     {
203                         ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aXValues(
204                             DataSeriesHelper::getAllDataSequencesByRole( xSource->getDataSequences(), C2U("values-x"), true ) );
205                         if( aXValues.empty() )
206                         {
207                             Reference< data::XLabeledDataSequence > xCategories( DiagramHelper::getCategoriesFromDiagram( xDiagram ) );
208                             if( xCategories.is() )
209                             {
210                                 Reference< data::XDataSequence > xSeq( xCategories->getValues());
211                                 if( xSeq.is() )
212                                 {
213                                     bool bHasValidDoubles = false;
214                                     double fTest=0.0;
215                                     Sequence< uno::Any > aCats( xSeq->getData() );
216                                     sal_Int32 nCount = aCats.getLength();
217                                     for( sal_Int32 i = 0; i < nCount; ++i )
218                                     {
219                                         if( (aCats[i]>>=fTest) && !::rtl::math::isNan(fTest) )
220                                         {
221                                             bHasValidDoubles=true;
222                                             break;
223                                         }
224                                     }
225                                     if( bHasValidDoubles )
226                                         nNumberFormatKey = DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier );
227                                 }
228                             }
229                         }
230                     }
231                 }
232                 bFormatSet = true;
233             }
234         }
235 
236         if( !bFormatSet )
237         {
238             typedef ::std::map< sal_Int32, sal_Int32 > tNumberformatFrequency;
239             tNumberformatFrequency aKeyMap;
240 
241             try
242             {
243                 Reference< XChartTypeContainer > xCTCnt( xCorrespondingCoordinateSystem, uno::UNO_QUERY_THROW );
244                 if( xCTCnt.is() )
245                 {
246                     ::rtl::OUString aRoleToMatch;
247                     if( nDimensionIndex == 0 )
248                         aRoleToMatch = C2U("values-x");
249                     Sequence< Reference< XChartType > > aChartTypes( xCTCnt->getChartTypes());
250                     for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
251                     {
252                         if( nDimensionIndex != 0 )
253                             aRoleToMatch = ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( aChartTypes[nCTIdx] );
254                         Reference< XDataSeriesContainer > xDSCnt( aChartTypes[nCTIdx], uno::UNO_QUERY_THROW );
255                         Sequence< Reference< XDataSeries > > aDataSeriesSeq( xDSCnt->getDataSeries());
256                         for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aDataSeriesSeq.getLength(); ++nSeriesIdx )
257                         {
258                             Reference< chart2::XDataSeries > xDataSeries(aDataSeriesSeq[nSeriesIdx]);
259                             Reference< data::XDataSource > xSource( xDataSeries, uno::UNO_QUERY_THROW );
260 
261                             if( nDimensionIndex == 1 )
262                             {
263                                 //only take those series into accoutn that are attached to this axis
264                                 sal_Int32 nAttachedAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
265                                 if( nAttachedAxisIndex != nAxisIndex )
266                                     continue;
267                             }
268 
269                             Reference< data::XLabeledDataSequence > xLabeledSeq(
270                                 DataSeriesHelper::getDataSequenceByRole( xSource, aRoleToMatch ) );
271 
272                             if( !xLabeledSeq.is() && nDimensionIndex==0 )
273                             {
274                                 ScaleData aData = xAxis->getScaleData();
275                                 xLabeledSeq = aData.Categories;
276                             }
277 
278                             if( xLabeledSeq.is() )
279                             {
280                                 Reference< data::XDataSequence > xSeq( xLabeledSeq->getValues());
281                                 if( xSeq.is() )
282                                 {
283                                     sal_Int32 nKey = xSeq->getNumberFormatKeyByIndex( -1 );
284                                     // initialize the value
285                                     if( aKeyMap.find( nKey ) == aKeyMap.end())
286                                         aKeyMap[ nKey ] = 0;
287                                     // increase frequency
288                                     aKeyMap[ nKey ] = (aKeyMap[ nKey ] + 1);
289                                 }
290                             }
291                         }
292                     }
293                 }
294             }
295             catch( const uno::Exception & ex )
296             {
297                 ASSERT_EXCEPTION( ex );
298             }
299 
300             if( ! aKeyMap.empty())
301             {
302                 sal_Int32 nMaxFreq = 0;
303                 // find most frequent key
304                 for( tNumberformatFrequency::const_iterator aIt = aKeyMap.begin();
305                     aIt != aKeyMap.end(); ++aIt )
306                 {
307                     OSL_TRACE( "NumberFormatKey %d appears %d times", (*aIt).first, (*aIt).second );
308                     // all values must at least be 1
309                     if( (*aIt).second > nMaxFreq )
310                     {
311                         nNumberFormatKey = (*aIt).first;
312                         bNumberFormatKeyFoundViaAttachedData = true;
313                         nMaxFreq = (*aIt).second;
314                     }
315                 }
316             }
317 
318             if( bSearchForParallelAxisIfNothingIsFound )
319             {
320                 //no format is set to this axis and no data is set to this axis
321                 //--> try to obtain the format from the parallel y-axis
322                 if( !bNumberFormatKeyFoundViaAttachedData && nDimensionIndex == 1 )
323                 {
324                     sal_Int32 nParallelAxisIndex = (nAxisIndex==1) ?0 :1;
325                     Reference< XAxis > xParallelAxis( AxisHelper::getAxis( 1, nParallelAxisIndex, xCorrespondingCoordinateSystem ) );
326                     nNumberFormatKey = AxisHelper::getExplicitNumberFormatKeyForAxis( xParallelAxis, xCorrespondingCoordinateSystem, xNumberFormatsSupplier, false );
327                 }
328             }
329         }
330     }
331     return nNumberFormatKey;
332 }
333 
334 Reference< XAxis > AxisHelper::createAxis(
335           sal_Int32 nDimensionIndex
336         , sal_Int32 nAxisIndex // 0==main or 1==secondary axis
337         , const Reference< XCoordinateSystem >& xCooSys
338         , const Reference< uno::XComponentContext > & xContext
339         , ReferenceSizeProvider * pRefSizeProvider )
340 {
341     if( !xContext.is() || !xCooSys.is() )
342         return NULL;
343     if( nDimensionIndex >= xCooSys->getDimension() )
344         return NULL;
345 
346     Reference< XAxis > xAxis( xContext->getServiceManager()->createInstanceWithContext(
347                     C2U( "com.sun.star.chart2.Axis" ), xContext ), uno::UNO_QUERY );
348 
349     OSL_ASSERT( xAxis.is());
350     if( xAxis.is())
351     {
352         xCooSys->setAxisByDimension( nDimensionIndex, xAxis, nAxisIndex );
353 
354         if( nAxisIndex>0 )//when inserting secondary axes copy some things from the main axis
355         {
356             ::com::sun::star::chart::ChartAxisPosition eNewAxisPos( ::com::sun::star::chart::ChartAxisPosition_END );
357 
358             Reference< XAxis > xMainAxis( xCooSys->getAxisByDimension( nDimensionIndex, 0 ) );
359             if( xMainAxis.is() )
360             {
361                 ScaleData aScale = xAxis->getScaleData();
362                 ScaleData aMainScale = xMainAxis->getScaleData();
363 
364                 aScale.AxisType = aMainScale.AxisType;
365                 aScale.AutoDateAxis = aMainScale.AutoDateAxis;
366                 aScale.Categories = aMainScale.Categories;
367                 aScale.Orientation = aMainScale.Orientation;
368 
369                 xAxis->setScaleData( aScale );
370 
371                 //ensure that the second axis is not placed on the main axis
372                 Reference< beans::XPropertySet > xMainProp( xMainAxis, uno::UNO_QUERY );
373                 if( xMainProp.is() )
374                 {
375                     ::com::sun::star::chart::ChartAxisPosition eMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO );
376                     xMainProp->getPropertyValue(C2U( "CrossoverPosition" )) >>= eMainAxisPos;
377                     if( ::com::sun::star::chart::ChartAxisPosition_END == eMainAxisPos )
378                         eNewAxisPos = ::com::sun::star::chart::ChartAxisPosition_START;
379                 }
380             }
381 
382             Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
383             if( xProp.is() )
384                 xProp->setPropertyValue(C2U( "CrossoverPosition" ), uno::makeAny(eNewAxisPos) );
385         }
386 
387         Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY );
388         if( xProp.is() ) try
389         {
390             // set correct initial AutoScale
391             if( pRefSizeProvider )
392                 pRefSizeProvider->setValuesAtPropertySet( xProp );
393         }
394         catch( uno::Exception& e )
395         {
396             ASSERT_EXCEPTION( e );
397         }
398     }
399     return xAxis;
400 }
401 
402 Reference< XAxis > AxisHelper::createAxis( sal_Int32 nDimensionIndex, bool bMainAxis
403                 , const Reference< chart2::XDiagram >& xDiagram
404                 , const Reference< uno::XComponentContext >& xContext
405                 , ReferenceSizeProvider * pRefSizeProvider )
406 {
407     OSL_ENSURE( xContext.is(), "need a context to create an axis" );
408     if( !xContext.is() )
409         return NULL;
410 
411     sal_Int32 nAxisIndex = bMainAxis ? MAIN_AXIS_INDEX : SECONDARY_AXIS_INDEX;
412     sal_Int32 nCooSysIndex = 0;
413     Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
414 
415     // create axis
416     return AxisHelper::createAxis(
417         nDimensionIndex, nAxisIndex, xCooSys, xContext, pRefSizeProvider );
418 }
419 
420 void AxisHelper::showAxis( sal_Int32 nDimensionIndex, bool bMainAxis
421                 , const Reference< chart2::XDiagram >& xDiagram
422                 , const Reference< uno::XComponentContext >& xContext
423                 , ReferenceSizeProvider * pRefSizeProvider )
424 {
425     if( !xDiagram.is() )
426         return;
427 
428     bool bNewAxisCreated = false;
429     Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
430     if( !xAxis.is() && xContext.is() )
431     {
432         // create axis
433         bNewAxisCreated = true;
434         xAxis.set( AxisHelper::createAxis( nDimensionIndex, bMainAxis, xDiagram, xContext, pRefSizeProvider ) );
435     }
436 
437     OSL_ASSERT( xAxis.is());
438     if( !bNewAxisCreated ) //default is true already if created
439         AxisHelper::makeAxisVisible( xAxis );
440 }
441 
442 void AxisHelper::showGrid( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
443                 , const Reference< XDiagram >& xDiagram
444                 , const Reference< uno::XComponentContext >& /*xContext*/ )
445 {
446     if( !xDiagram.is() )
447         return;
448 
449     Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
450     if(!xCooSys.is())
451         return;
452 
453     Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys ) );
454     if(!xAxis.is())
455     {
456         //hhhh todo create axis without axis visibility
457     }
458     if(!xAxis.is())
459         return;
460 
461     if( bMainGrid )
462         AxisHelper::makeGridVisible( xAxis->getGridProperties() );
463     else
464     {
465         Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
466         for( sal_Int32 nN=0; nN<aSubGrids.getLength(); nN++)
467             AxisHelper::makeGridVisible( aSubGrids[nN] );
468     }
469 }
470 
471 void AxisHelper::makeAxisVisible( const Reference< XAxis >& xAxis )
472 {
473     Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
474     if( xProps.is() )
475     {
476         xProps->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_True ) );
477         LineProperties::SetLineVisible( xProps );
478         xProps->setPropertyValue( C2U( "DisplayLabels" ), uno::makeAny( sal_True ) );
479     }
480 }
481 
482 void AxisHelper::makeGridVisible( const Reference< beans::XPropertySet >& xGridProperties )
483 {
484     if( xGridProperties.is() )
485     {
486         xGridProperties->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_True ) );
487         LineProperties::SetLineVisible( xGridProperties );
488     }
489 }
490 
491 void AxisHelper::hideAxis( sal_Int32 nDimensionIndex, bool bMainAxis
492                 , const Reference< XDiagram >& xDiagram )
493 {
494     AxisHelper::makeAxisInvisible( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
495 }
496 
497 void AxisHelper::makeAxisInvisible( const Reference< XAxis >& xAxis )
498 {
499     Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
500     if( xProps.is() )
501     {
502         xProps->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_False ) );
503     }
504 }
505 
506 void AxisHelper::hideAxisIfNoDataIsAttached( const Reference< XAxis >& xAxis, const Reference< XDiagram >& xDiagram )
507 {
508     //axis is hidden if no data is attached anymore but data is available
509     bool bOtherSeriesAttachedToThisAxis = false;
510     ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
511     ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt = aSeriesVector.begin();
512     for( ; aIt != aSeriesVector.end(); ++aIt)
513     {
514         uno::Reference< chart2::XAxis > xCurrentAxis( DiagramHelper::getAttachedAxis( *aIt, xDiagram ), uno::UNO_QUERY );
515         if( xCurrentAxis==xAxis )
516         {
517             bOtherSeriesAttachedToThisAxis = true;
518             break;
519         }
520     }
521     if(!bOtherSeriesAttachedToThisAxis && !aSeriesVector.empty() )
522         AxisHelper::makeAxisInvisible( xAxis );
523 }
524 
525 void AxisHelper::hideGrid( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
526                 , const Reference< XDiagram >& xDiagram )
527 {
528     if( !xDiagram.is() )
529         return;
530 
531     Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
532     if(!xCooSys.is())
533         return;
534 
535     Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys ) );
536     if(!xAxis.is())
537         return;
538 
539     if( bMainGrid )
540         AxisHelper::makeGridInvisible( xAxis->getGridProperties() );
541     else
542     {
543         Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
544         for( sal_Int32 nN=0; nN<aSubGrids.getLength(); nN++)
545             AxisHelper::makeGridInvisible( aSubGrids[nN] );
546     }
547 }
548 
549 void AxisHelper::makeGridInvisible( const Reference< beans::XPropertySet >& xGridProperties )
550 {
551     if( xGridProperties.is() )
552     {
553         xGridProperties->setPropertyValue( C2U( "Show" ), uno::makeAny( sal_False ) );
554     }
555 }
556 
557 sal_Bool AxisHelper::isGridShown( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
558                 , const Reference< ::com::sun::star::chart2::XDiagram >& xDiagram )
559 {
560     sal_Bool bRet = false;
561 
562     Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
563     if(!xCooSys.is())
564         return bRet;
565 
566     Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys ) );
567     if(!xAxis.is())
568         return bRet;
569 
570     if( bMainGrid )
571         bRet = AxisHelper::isGridVisible( xAxis->getGridProperties() );
572     else
573     {
574         Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
575         if( aSubGrids.getLength() )
576             bRet = AxisHelper::isGridVisible( aSubGrids[0] );
577     }
578 
579     return bRet;
580 }
581 
582 Reference< XCoordinateSystem > AxisHelper::getCoordinateSystemByIndex(
583     const Reference< XDiagram >& xDiagram, sal_Int32 nIndex )
584 {
585     Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
586     if(!xCooSysContainer.is())
587         return NULL;
588     Sequence< Reference< XCoordinateSystem > > aCooSysList = xCooSysContainer->getCoordinateSystems();
589     if(0<=nIndex && nIndex<aCooSysList.getLength())
590         return aCooSysList[nIndex];
591     return NULL;
592 }
593 
594 Reference< XAxis > AxisHelper::getAxis( sal_Int32 nDimensionIndex, bool bMainAxis
595             , const Reference< XDiagram >& xDiagram )
596 {
597     Reference< XAxis > xRet;
598     try
599     {
600         Reference< XCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 );
601         xRet.set( AxisHelper::getAxis( nDimensionIndex, bMainAxis ? 0 : 1, xCooSys ) );
602     }
603     catch( const uno::Exception & )
604     {
605     }
606     return xRet;
607 }
608 
609 Reference< XAxis > AxisHelper::getAxis( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex
610             , const Reference< XCoordinateSystem >& xCooSys )
611 {
612     Reference< XAxis > xRet;
613     try
614     {
615         if( xCooSys.is() )
616             xRet.set( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
617     }
618     catch( const uno::Exception & )
619     {
620     }
621     return xRet;
622 }
623 
624 Reference< XAxis > AxisHelper::getCrossingMainAxis( const Reference< XAxis >& xAxis
625             , const Reference< XCoordinateSystem >& xCooSys )
626 {
627     sal_Int32 nDimensionIndex = 0;
628     sal_Int32 nAxisIndex = 0;
629     AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex );
630     if( 2==nDimensionIndex )
631     {
632         nDimensionIndex=1;
633         bool bSwapXY = false;
634         Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY );
635         if( xCooSysProp.is() && (xCooSysProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bSwapXY) && bSwapXY )
636             nDimensionIndex=0;
637     }
638     else if( 1==nDimensionIndex )
639         nDimensionIndex=0;
640     else
641         nDimensionIndex=1;
642     return AxisHelper::getAxis( nDimensionIndex, 0, xCooSys );
643 }
644 
645 Reference< XAxis > AxisHelper::getParallelAxis( const Reference< XAxis >& xAxis
646             , const Reference< XDiagram >& xDiagram )
647 {
648     try
649     {
650         sal_Int32 nCooSysIndex=-1;
651         sal_Int32 nDimensionIndex=-1;
652         sal_Int32 nAxisIndex=-1;
653         if( getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex ) )
654         {
655             sal_Int32 nParallelAxisIndex = (nAxisIndex==1) ?0 :1;
656             return getAxis( nDimensionIndex, nParallelAxisIndex, getCoordinateSystemByIndex( xDiagram, nCooSysIndex ) );
657         }
658     }
659     catch( uno::RuntimeException& )
660     {
661     }
662     return 0;
663 }
664 
665 sal_Bool AxisHelper::isAxisShown( sal_Int32 nDimensionIndex, bool bMainAxis
666             , const Reference< XDiagram >& xDiagram )
667 {
668     return AxisHelper::isAxisVisible( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
669 }
670 
671 sal_Bool AxisHelper::isAxisVisible( const Reference< XAxis >& xAxis )
672 {
673     sal_Bool bRet = false;
674 
675     Reference< beans::XPropertySet > xProps( xAxis, uno::UNO_QUERY );
676     if( xProps.is() )
677     {
678         xProps->getPropertyValue( C2U( "Show" ) ) >>= bRet;
679         bRet = bRet && ( LineProperties::IsLineVisible( xProps )
680             || areAxisLabelsVisible( xProps ) );
681     }
682 
683     return bRet;
684 }
685 
686 sal_Bool AxisHelper::areAxisLabelsVisible( const Reference< beans::XPropertySet >& xAxisProperties )
687 {
688     sal_Bool bRet = false;
689     if( xAxisProperties.is() )
690     {
691         xAxisProperties->getPropertyValue( C2U( "DisplayLabels" ) ) >>= bRet;
692     }
693     return bRet;
694 }
695 
696 sal_Bool AxisHelper::isGridVisible( const Reference< beans::XPropertySet >& xGridProperies )
697 {
698     sal_Bool bRet = false;
699 
700     if( xGridProperies.is() )
701     {
702         xGridProperies->getPropertyValue( C2U( "Show" ) ) >>= bRet;
703         bRet = bRet && LineProperties::IsLineVisible( xGridProperies );
704     }
705 
706     return bRet;
707 }
708 
709 Reference< beans::XPropertySet > AxisHelper::getGridProperties(
710             const Reference< XCoordinateSystem >& xCooSys
711         , sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex, sal_Int32 nSubGridIndex )
712 {
713     Reference< beans::XPropertySet > xRet;
714 
715     Reference< XAxis > xAxis( AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys ) );
716     if( xAxis.is() )
717     {
718         if( nSubGridIndex<0 )
719             xRet.set( xAxis->getGridProperties() );
720         else
721         {
722             Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );
723             if( nSubGridIndex >= 0 && nSubGridIndex < aSubGrids.getLength() )
724                 xRet.set( aSubGrids[nSubGridIndex] );
725         }
726     }
727 
728     return xRet;
729 }
730 
731 sal_Int32 AxisHelper::getDimensionIndexOfAxis(
732               const Reference< XAxis >& xAxis
733             , const Reference< XDiagram >& xDiagram )
734 {
735     sal_Int32 nDimensionIndex = -1;
736     sal_Int32 nCooSysIndex = -1;
737     sal_Int32 nAxisIndex = -1;
738     AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex , nDimensionIndex, nAxisIndex );
739     return nDimensionIndex;
740 }
741 
742 bool AxisHelper::getIndicesForAxis(
743               const Reference< XAxis >& xAxis
744             , const Reference< XCoordinateSystem >& xCooSys
745             , sal_Int32& rOutDimensionIndex, sal_Int32& rOutAxisIndex )
746 {
747     //returns true if indices are found
748 
749     rOutDimensionIndex = -1;
750     rOutAxisIndex = -1;
751 
752     if( xCooSys.is() && xAxis.is() )
753     {
754         Reference< XAxis > xCurrentAxis;
755         sal_Int32 nDimensionCount( xCooSys->getDimension() );
756         for( sal_Int32 nDimensionIndex = 0; nDimensionIndex < nDimensionCount; nDimensionIndex++ )
757         {
758             sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
759             for( sal_Int32 nAxisIndex = 0; nAxisIndex <= nMaxAxisIndex; nAxisIndex++ )
760             {
761                  xCurrentAxis = xCooSys->getAxisByDimension(nDimensionIndex,nAxisIndex);
762                  if( xCurrentAxis == xAxis )
763                  {
764                      rOutDimensionIndex = nDimensionIndex;
765                      rOutAxisIndex = nAxisIndex;
766                      return true;
767                  }
768             }
769         }
770     }
771     return false;
772 }
773 
774 bool AxisHelper::getIndicesForAxis( const Reference< XAxis >& xAxis, const Reference< XDiagram >& xDiagram
775             , sal_Int32& rOutCooSysIndex, sal_Int32& rOutDimensionIndex, sal_Int32& rOutAxisIndex )
776 {
777     //returns true if indices are found
778 
779     rOutCooSysIndex = -1;
780     rOutDimensionIndex = -1;
781     rOutAxisIndex = -1;
782 
783     Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
784     if(xCooSysContainer.is())
785     {
786         Sequence< Reference< XCoordinateSystem > > aCooSysList = xCooSysContainer->getCoordinateSystems();
787         for( sal_Int32 nC=0; nC<aCooSysList.getLength(); ++nC )
788         {
789             if( AxisHelper::getIndicesForAxis( xAxis, aCooSysList[nC], rOutDimensionIndex, rOutAxisIndex ) )
790             {
791                 rOutCooSysIndex = nC;
792                 return true;
793             }
794         }
795     }
796 
797     return false;
798 }
799 
800 std::vector< Reference< XAxis > > AxisHelper::getAllAxesOfCoordinateSystem(
801       const Reference< XCoordinateSystem >& xCooSys
802     , bool bOnlyVisible /* = false */ )
803 {
804     std::vector< Reference< XAxis > > aAxisVector;
805 
806     if(xCooSys.is())
807     {
808         sal_Int32 nDimensionIndex = 0;
809         sal_Int32 nMaxDimensionIndex = xCooSys->getDimension() -1;
810         if( nMaxDimensionIndex>=0 )
811         {
812             for(nDimensionIndex=0; nDimensionIndex<=nMaxDimensionIndex; ++nDimensionIndex)
813             {
814                 const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
815                 for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
816                 {
817                     try
818                     {
819                         Reference< XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
820                         bool bAddAxis = true;
821                         if( xAxis.is() )
822                         {
823                             if( bOnlyVisible )
824                             {
825                                 Reference< beans::XPropertySet > xAxisProp( xAxis, uno::UNO_QUERY );
826                                 if( !xAxisProp.is() ||
827                                     !(xAxisProp->getPropertyValue( C2U("Show")) >>= bAddAxis) )
828                                     bAddAxis = false;
829                             }
830                             if( bAddAxis )
831                                 aAxisVector.push_back( xAxis );
832                         }
833                     }
834                     catch( const uno::Exception & ex )
835                     {
836                         ASSERT_EXCEPTION( ex );
837                     }
838                 }
839             }
840         }
841     }
842 
843     return aAxisVector;
844 }
845 
846 Sequence< Reference< XAxis > > AxisHelper::getAllAxesOfDiagram(
847       const Reference< XDiagram >& xDiagram
848     , bool bOnlyVisible )
849 {
850     std::vector< Reference< XAxis > > aAxisVector;
851 
852     Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
853     if(xCooSysContainer.is())
854     {
855         Sequence< Reference< XCoordinateSystem > > aCooSysList = xCooSysContainer->getCoordinateSystems();
856         sal_Int32 nC = 0;
857         for( nC=0; nC<aCooSysList.getLength(); ++nC )
858         {
859             std::vector< Reference< XAxis > > aAxesPerCooSys( AxisHelper::getAllAxesOfCoordinateSystem( aCooSysList[nC], bOnlyVisible ) );
860             aAxisVector.insert( aAxisVector.end(), aAxesPerCooSys.begin(), aAxesPerCooSys.end() );
861         }
862     }
863 
864     return ContainerHelper::ContainerToSequence( aAxisVector );
865 }
866 
867 Sequence< Reference< beans::XPropertySet > > AxisHelper::getAllGrids( const Reference< XDiagram >& xDiagram )
868 {
869     Sequence< Reference< XAxis > > aAllAxes( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
870     std::vector< Reference< beans::XPropertySet > > aGridVector;
871 
872     sal_Int32 nA = 0;
873     for( nA=0; nA<aAllAxes.getLength(); ++nA )
874     {
875         Reference< XAxis > xAxis( aAllAxes[nA] );
876         if(!xAxis.is())
877             continue;
878         Reference< beans::XPropertySet > xGridProperties( xAxis->getGridProperties() );
879         if( xGridProperties.is() )
880             aGridVector.push_back( xGridProperties );
881 
882         Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );;
883         sal_Int32 nSubGrid = 0;
884         for( nSubGrid = 0; nSubGrid < aSubGrids.getLength(); ++nSubGrid )
885         {
886             Reference< beans::XPropertySet > xSubGrid( aSubGrids[nSubGrid] );
887             if( xSubGrid.is() )
888                 aGridVector.push_back( xSubGrid );
889         }
890     }
891 
892     return ContainerHelper::ContainerToSequence( aGridVector );
893 }
894 
895 void AxisHelper::getAxisOrGridPossibilities( Sequence< sal_Bool >& rPossibilityList
896         , const Reference< XDiagram>& xDiagram, sal_Bool bAxis )
897 {
898     rPossibilityList.realloc(6);
899 
900     sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
901 
902     //set possibilities:
903     sal_Int32 nIndex=0;
904     Reference< XChartType > xChartType = DiagramHelper::getChartTypeByIndex( xDiagram, 0 );
905     for(nIndex=0;nIndex<3;nIndex++)
906         rPossibilityList[nIndex]=ChartTypeHelper::isSupportingMainAxis(xChartType,nDimensionCount,nIndex);
907     for(nIndex=3;nIndex<6;nIndex++)
908         if( bAxis )
909             rPossibilityList[nIndex]=ChartTypeHelper::isSupportingSecondaryAxis(xChartType,nDimensionCount,nIndex-3);
910         else
911             rPossibilityList[nIndex] = rPossibilityList[nIndex-3];
912 }
913 
914 bool AxisHelper::isSecondaryYAxisNeeded( const Reference< XCoordinateSystem >& xCooSys )
915 {
916     Reference< chart2::XChartTypeContainer > xCTCnt( xCooSys, uno::UNO_QUERY );
917     if( xCTCnt.is() )
918     {
919         Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes() );
920         for( sal_Int32 i=0; i<aChartTypes.getLength(); ++i )
921         {
922             Reference< XDataSeriesContainer > xSeriesContainer( aChartTypes[i] , uno::UNO_QUERY );
923             if( !xSeriesContainer.is() )
924                     continue;
925 
926             Sequence< Reference< XDataSeries > > aSeriesList( xSeriesContainer->getDataSeries() );
927             for( sal_Int32 nS = aSeriesList.getLength(); nS-- ; )
928             {
929                 Reference< beans::XPropertySet > xProp( aSeriesList[nS], uno::UNO_QUERY );
930 		        if(xProp.is())
931                 {
932                     sal_Int32 nAttachedAxisIndex = 0;
933                     if( ( xProp->getPropertyValue( C2U( "AttachedAxisIndex" ) ) >>= nAttachedAxisIndex ) && nAttachedAxisIndex>0 )
934                         return true;
935                 }
936             }
937         }
938     }
939     return false;
940 }
941 
942 bool AxisHelper::shouldAxisBeDisplayed( const Reference< XAxis >& xAxis
943                                        , const Reference< XCoordinateSystem >& xCooSys )
944 {
945     bool bRet = false;
946 
947     if( xAxis.is() && xCooSys.is() )
948     {
949         sal_Int32 nDimensionIndex=-1;
950         sal_Int32 nAxisIndex=-1;
951         if( AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) )
952         {
953             sal_Int32 nDimensionCount = xCooSys->getDimension();
954             Reference< XChartType > xChartType( AxisHelper::getChartTypeByIndex( xCooSys, 0 ) );
955 
956             bool bMainAxis = (nAxisIndex==MAIN_AXIS_INDEX);
957             if( bMainAxis )
958                 bRet = ChartTypeHelper::isSupportingMainAxis(xChartType,nDimensionCount,nDimensionIndex);
959             else
960                 bRet = ChartTypeHelper::isSupportingSecondaryAxis(xChartType,nDimensionCount,nDimensionIndex);
961         }
962     }
963 
964     return bRet;
965 }
966 
967 void AxisHelper::getAxisOrGridExcistence( Sequence< sal_Bool >& rExistenceList
968         , const Reference< XDiagram>& xDiagram, sal_Bool bAxis )
969 {
970     rExistenceList.realloc(6);
971 
972     if(bAxis)
973     {
974         sal_Int32 nN;
975         Reference< XAxis > xAxis;
976         for(nN=0;nN<3;nN++)
977             rExistenceList[nN] = AxisHelper::isAxisShown( nN, true, xDiagram );
978         for(nN=3;nN<6;nN++)
979             rExistenceList[nN] = AxisHelper::isAxisShown( nN%3, false, xDiagram );
980     }
981     else
982     {
983         sal_Int32 nN;
984 
985         for(nN=0;nN<3;nN++)
986             rExistenceList[nN] = AxisHelper::isGridShown( nN, 0, true, xDiagram );
987         for(nN=3;nN<6;nN++)
988             rExistenceList[nN] = AxisHelper::isGridShown( nN%3, 0, false, xDiagram );
989     }
990 }
991 
992 bool AxisHelper::changeVisibilityOfAxes( const Reference< XDiagram >& xDiagram
993                         , const Sequence< sal_Bool >& rOldExistenceList
994                         , const Sequence< sal_Bool >& rNewExistenceList
995                         , const Reference< uno::XComponentContext >& xContext
996                         , ReferenceSizeProvider * pRefSizeProvider )
997 {
998     bool bChanged = false;
999     for(sal_Int32 nN=0;nN<6;nN++)
1000     {
1001         if(rOldExistenceList[nN]!=rNewExistenceList[nN])
1002         {
1003             bChanged = true;
1004             if(rNewExistenceList[nN])
1005             {
1006                 AxisHelper::showAxis( nN%3, nN<3, xDiagram, xContext, pRefSizeProvider );
1007             }
1008             else
1009                 AxisHelper::hideAxis( nN%3, nN<3, xDiagram );
1010         }
1011     }
1012     return bChanged;
1013 }
1014 
1015 bool AxisHelper::changeVisibilityOfGrids( const Reference< XDiagram >& xDiagram
1016                         , const Sequence< sal_Bool >& rOldExistenceList
1017                         , const Sequence< sal_Bool >& rNewExistenceList
1018                         , const Reference< uno::XComponentContext >& xContext )
1019 {
1020     bool bChanged = false;
1021     for(sal_Int32 nN=0;nN<6;nN++)
1022     {
1023         if(rOldExistenceList[nN]!=rNewExistenceList[nN])
1024         {
1025             bChanged = true;
1026             if(rNewExistenceList[nN])
1027                 AxisHelper::showGrid( nN%3, 0, nN<3, xDiagram, xContext );
1028             else
1029                 AxisHelper::hideGrid( nN%3, 0, nN<3, xDiagram );
1030         }
1031     }
1032     return bChanged;
1033 }
1034 
1035 Reference< XCoordinateSystem > AxisHelper::getCoordinateSystemOfAxis(
1036               const Reference< XAxis >& xAxis
1037             , const Reference< XDiagram >& xDiagram )
1038 {
1039     Reference< XCoordinateSystem > xRet;
1040 
1041     Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
1042     if( xCooSysContainer.is() )
1043     {
1044         Reference< XCoordinateSystem > xCooSys;
1045         Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
1046         for( sal_Int32 nCooSysIndex = 0; nCooSysIndex < aCooSysList.getLength(); ++nCooSysIndex )
1047         {
1048             xCooSys = aCooSysList[nCooSysIndex];
1049             std::vector< Reference< XAxis > > aAllAxis( AxisHelper::getAllAxesOfCoordinateSystem( xCooSys ) );
1050 
1051             ::std::vector< Reference< XAxis > >::iterator aFound =
1052                   ::std::find( aAllAxis.begin(), aAllAxis.end(), xAxis );
1053             if( aFound != aAllAxis.end())
1054             {
1055                 xRet.set( xCooSys );
1056                 break;
1057             }
1058         }
1059     }
1060     return xRet;
1061 }
1062 
1063 Reference< XChartType > AxisHelper::getChartTypeByIndex( const Reference< XCoordinateSystem >& xCooSys, sal_Int32 nIndex )
1064 {
1065     Reference< XChartType > xChartType;
1066 
1067     Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
1068     if( xChartTypeContainer.is() )
1069     {
1070         Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
1071         if( nIndex >= 0 && nIndex < aChartTypeList.getLength() )
1072             xChartType.set( aChartTypeList[nIndex] );
1073     }
1074 
1075     return xChartType;
1076 }
1077 
1078 void AxisHelper::setRTLAxisLayout( const Reference< XCoordinateSystem >& xCooSys )
1079 {
1080     if( xCooSys.is() )
1081     {
1082         bool bCartesian = xCooSys->getViewServiceName().equals( CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME );
1083         if( bCartesian )
1084         {
1085             bool bVertical = false;
1086             Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY );
1087             if( xCooSysProp.is() )
1088                 xCooSysProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bVertical;
1089 
1090             sal_Int32 nHorizontalAxisDimension = bVertical ? 1 : 0;
1091             sal_Int32 nVerticalAxisDimension = bVertical ? 0 : 1;
1092 
1093             try
1094             {
1095                 //reverse direction for horizontal main axis
1096                 Reference< chart2::XAxis > xHorizontalMainAxis( AxisHelper::getAxis( nHorizontalAxisDimension, MAIN_AXIS_INDEX, xCooSys ) );
1097                 if( xHorizontalMainAxis.is() )
1098                 {
1099                     chart2::ScaleData aScale = xHorizontalMainAxis->getScaleData();
1100                     aScale.Orientation = chart2::AxisOrientation_REVERSE;
1101                     xHorizontalMainAxis->setScaleData(aScale);
1102                 }
1103 
1104                 //mathematical direction for vertical main axis
1105                 Reference< chart2::XAxis > xVerticalMainAxis( AxisHelper::getAxis( nVerticalAxisDimension, MAIN_AXIS_INDEX, xCooSys ) );
1106                 if( xVerticalMainAxis.is() )
1107                 {
1108                     chart2::ScaleData aScale = xVerticalMainAxis->getScaleData();
1109                     aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL;
1110                     xVerticalMainAxis->setScaleData(aScale);
1111                 }
1112             }
1113             catch( uno::Exception & ex )
1114             {
1115                 ASSERT_EXCEPTION( ex );
1116             }
1117 
1118             try
1119             {
1120                 //reverse direction for horizontal secondary axis
1121                 Reference< chart2::XAxis > xHorizontalSecondaryAxis( AxisHelper::getAxis( nHorizontalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys ) );
1122                 if( xHorizontalSecondaryAxis.is() )
1123                 {
1124                     chart2::ScaleData aScale = xHorizontalSecondaryAxis->getScaleData();
1125                     aScale.Orientation = chart2::AxisOrientation_REVERSE;
1126                     xHorizontalSecondaryAxis->setScaleData(aScale);
1127                 }
1128 
1129                 //mathematical direction for vertical secondary axis
1130                 Reference< chart2::XAxis > xVerticalSecondaryAxis( AxisHelper::getAxis( nVerticalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys ) );
1131                 if( xVerticalSecondaryAxis.is() )
1132                 {
1133                     chart2::ScaleData aScale = xVerticalSecondaryAxis->getScaleData();
1134                     aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL;
1135                     xVerticalSecondaryAxis->setScaleData(aScale);
1136                 }
1137             }
1138             catch( uno::Exception & ex )
1139             {
1140                 ASSERT_EXCEPTION( ex );
1141             }
1142         }
1143     }
1144 }
1145 
1146 Reference< XChartType > AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const Reference< chart2::XDiagram >& xDiagram, const sal_Int32 nAttachedAxisIndex )
1147 {
1148     Reference< XChartType > xChartType;
1149     ::std::vector< Reference< XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
1150     ::std::vector< Reference< XDataSeries > >::const_iterator aIter = aSeriesVector.begin();
1151     for( ; aIter != aSeriesVector.end(); aIter++ )
1152     {
1153         sal_Int32 nCurrentIndex = DataSeriesHelper::getAttachedAxisIndex( *aIter );
1154         if( nAttachedAxisIndex == nCurrentIndex )
1155         {
1156             xChartType = DiagramHelper::getChartTypeOfSeries( xDiagram, *aIter );
1157             if(xChartType.is())
1158                 break;
1159         }
1160     }
1161     return xChartType;
1162 }
1163 
1164 bool AxisHelper::isAxisPositioningEnabled()
1165 {
1166     const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
1167     return nCurrentVersion >= SvtSaveOptions::ODFVER_012;
1168 }
1169 
1170 //.............................................................................
1171 } //namespace chart
1172 //.............................................................................
1173