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