1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "WrappedScaleProperty.hxx"
21 #include "Chart2ModelContact.hxx"
22 #include <CommonConverters.hxx>
24 #include <AxisHelper.hxx>
25 #include <com/sun/star/chart2/AxisType.hpp>
26 #include <com/sun/star/chart2/XAxis.hpp>
27 #include <com/sun/star/chart/ChartAxisType.hpp>
28 #include <chartview/ExplicitScaleValues.hxx>
30 #include <osl/diagnose.h>
32 using namespace ::com::sun::star
;
33 using ::com::sun::star::uno::Any
;
34 using namespace ::com::sun::star::chart2
;
35 using ::com::sun::star::uno::Reference
;
36 using ::com::sun::star::uno::Sequence
;
37 using ::com::sun::star::chart::TimeIncrement
;
39 namespace chart::wrapper
42 WrappedScaleProperty::WrappedScaleProperty(tScaleProperty eScaleProperty
43 , std::shared_ptr
<Chart2ModelContact
> spChart2ModelContact
)
44 : WrappedProperty(OUString(),OUString())
45 , m_spChart2ModelContact(std::move( spChart2ModelContact
))
46 , m_eScaleProperty( eScaleProperty
)
48 switch( m_eScaleProperty
)
56 case SCALE_PROP_ORIGIN
:
57 m_aOuterName
= "Origin";
59 case SCALE_PROP_STEPMAIN
:
60 m_aOuterName
= "StepMain";
62 case SCALE_PROP_STEPHELP
:
63 m_aOuterName
= "StepHelp";
65 case SCALE_PROP_STEPHELP_COUNT
:
66 m_aOuterName
= "StepHelpCount";
68 case SCALE_PROP_AUTO_MAX
:
69 m_aOuterName
= "AutoMax";
71 case SCALE_PROP_AUTO_MIN
:
72 m_aOuterName
= "AutoMin";
74 case SCALE_PROP_AUTO_ORIGIN
:
75 m_aOuterName
= "AutoOrigin";
77 case SCALE_PROP_AUTO_STEPMAIN
:
78 m_aOuterName
= "AutoStepMain";
80 case SCALE_PROP_AUTO_STEPHELP
:
81 m_aOuterName
= "AutoStepHelp";
83 case SCALE_PROP_AXIS_TYPE
:
84 m_aOuterName
= "AxisType";
86 case SCALE_PROP_DATE_INCREMENT
:
87 m_aOuterName
= "TimeIncrement";
89 case SCALE_PROP_EXPLICIT_DATE_INCREMENT
:
90 m_aOuterName
= "ExplicitTimeIncrement";
92 case SCALE_PROP_LOGARITHMIC
:
93 m_aOuterName
= "Logarithmic";
95 case SCALE_PROP_REVERSEDIRECTION
:
96 m_aOuterName
= "ReverseDirection";
99 OSL_FAIL("unknown scale property");
104 WrappedScaleProperty::~WrappedScaleProperty()
108 void WrappedScaleProperty::addWrappedProperties( std::vector
< std::unique_ptr
<WrappedProperty
> >& rList
109 , const std::shared_ptr
< Chart2ModelContact
>& spChart2ModelContact
)
111 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_MAX
, spChart2ModelContact
) );
112 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_MIN
, spChart2ModelContact
) );
113 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_ORIGIN
, spChart2ModelContact
) );
114 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_STEPMAIN
, spChart2ModelContact
) );
115 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_STEPHELP
, spChart2ModelContact
) );
116 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_STEPHELP_COUNT
, spChart2ModelContact
) );
117 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_AUTO_MAX
, spChart2ModelContact
) );
118 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_AUTO_MIN
, spChart2ModelContact
) );
119 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_AUTO_ORIGIN
, spChart2ModelContact
) );
120 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_AUTO_STEPMAIN
, spChart2ModelContact
) );
121 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_AUTO_STEPHELP
, spChart2ModelContact
) );
122 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_AXIS_TYPE
, spChart2ModelContact
) );
123 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_DATE_INCREMENT
, spChart2ModelContact
) );
124 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_EXPLICIT_DATE_INCREMENT
, spChart2ModelContact
) );
125 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_LOGARITHMIC
, spChart2ModelContact
) );
126 rList
.emplace_back( new WrappedScaleProperty( SCALE_PROP_REVERSEDIRECTION
, spChart2ModelContact
) );
129 void WrappedScaleProperty::setPropertyValue( const Any
& rOuterValue
, const Reference
< beans::XPropertySet
>& xInnerPropertySet
) const
131 setPropertyValue( m_eScaleProperty
, rOuterValue
, xInnerPropertySet
);
134 Any
WrappedScaleProperty::getPropertyValue( const Reference
< beans::XPropertySet
>& xInnerPropertySet
) const
136 return getPropertyValue( m_eScaleProperty
, xInnerPropertySet
);
139 void WrappedScaleProperty::setPropertyValue( tScaleProperty eScaleProperty
, const Any
& rOuterValue
, const Reference
< beans::XPropertySet
>& xInnerPropertySet
) const
141 m_aOuterValue
= rOuterValue
;
143 Reference
< chart2::XAxis
> xAxis( xInnerPropertySet
, uno::UNO_QUERY
);
144 OSL_ENSURE(xAxis
.is(),"need an XAxis");
148 bool bSetScaleData
= false;
150 chart2::ScaleData
aScaleData( xAxis
->getScaleData() );
153 switch( eScaleProperty
)
157 aScaleData
.Maximum
= rOuterValue
;
158 bSetScaleData
= true;
163 aScaleData
.Minimum
= rOuterValue
;
164 bSetScaleData
= true;
167 case SCALE_PROP_STEPMAIN
:
169 aScaleData
.IncrementData
.Distance
= rOuterValue
;
170 bSetScaleData
= true;
173 case SCALE_PROP_STEPHELP
:
175 Sequence
< chart2::SubIncrement
>& rSubIncrements( aScaleData
.IncrementData
.SubIncrements
);
176 if( !rSubIncrements
.hasElements() )
177 rSubIncrements
.realloc( 1 );
178 auto pSubIncrements
= rSubIncrements
.getArray();
180 double fStepHelp
= 0;
181 if( rOuterValue
>>= fStepHelp
)
183 double fStepMain
= 0;
184 if( AxisHelper::isLogarithmic(aScaleData
.Scaling
) )
186 sal_Int32 nIntervalCount
= static_cast< sal_Int32
>(fStepHelp
);
187 pSubIncrements
[ 0 ].IntervalCount
<<= nIntervalCount
;
189 else if( (fStepHelp
!= 0.0) &&
190 (aScaleData
.IncrementData
.Distance
>>= fStepMain
) )
192 // approximate interval count
193 sal_Int32 nIntervalCount
= static_cast< sal_Int32
>(fStepMain
/ fStepHelp
);//cppcheck-suppress zerodiv
194 pSubIncrements
[ 0 ].IntervalCount
<<= nIntervalCount
;
197 bSetScaleData
= true;
200 case SCALE_PROP_STEPHELP_COUNT
:
202 Sequence
< chart2::SubIncrement
>& rSubIncrements( aScaleData
.IncrementData
.SubIncrements
);
203 if( !rSubIncrements
.hasElements() )
204 rSubIncrements
.realloc( 1 );
205 auto pSubIncrements
= rSubIncrements
.getArray();
206 sal_Int32 nIntervalCount
=0;
207 if( rOuterValue
>>=nIntervalCount
)
208 pSubIncrements
[ 0 ].IntervalCount
<<= nIntervalCount
;
210 pSubIncrements
[ 0 ].IntervalCount
= Any();
211 bSetScaleData
= true;
214 case SCALE_PROP_AUTO_MAX
:
216 if( (rOuterValue
>>= bBool
) && bBool
)
217 aScaleData
.Maximum
= Any();
219 aScaleData
.Maximum
= getPropertyValue( SCALE_PROP_MAX
, xInnerPropertySet
);
220 bSetScaleData
= true;
223 case SCALE_PROP_AUTO_MIN
:
225 if( (rOuterValue
>>= bBool
) && bBool
)
226 aScaleData
.Minimum
= Any();
228 aScaleData
.Minimum
= getPropertyValue( SCALE_PROP_MIN
, xInnerPropertySet
);
229 bSetScaleData
= true;
232 case SCALE_PROP_AUTO_STEPMAIN
:
234 if( (rOuterValue
>>= bBool
) && bBool
)
235 aScaleData
.IncrementData
.Distance
= Any();
237 aScaleData
.IncrementData
.Distance
= getPropertyValue( SCALE_PROP_STEPMAIN
, xInnerPropertySet
);
238 bSetScaleData
= true;
241 case SCALE_PROP_AUTO_STEPHELP
:
243 Sequence
< chart2::SubIncrement
>& rSubIncrements( aScaleData
.IncrementData
.SubIncrements
);
244 if( !rSubIncrements
.hasElements() )
245 rSubIncrements
.realloc( 1 );
246 auto pSubIncrements
= rSubIncrements
.getArray();
248 if( (rOuterValue
>>= bBool
) && bBool
)
249 pSubIncrements
[ 0 ].IntervalCount
= Any();
251 pSubIncrements
[ 0 ].IntervalCount
= getPropertyValue( SCALE_PROP_STEPHELP_COUNT
, xInnerPropertySet
);
252 bSetScaleData
= true;
255 case SCALE_PROP_ORIGIN
:
257 aScaleData
.Origin
= rOuterValue
;
258 bSetScaleData
= true;
261 case SCALE_PROP_AUTO_ORIGIN
:
263 if( (rOuterValue
>>= bBool
) && bBool
)
264 aScaleData
.Origin
= Any();
266 aScaleData
.Origin
= getPropertyValue( SCALE_PROP_ORIGIN
, xInnerPropertySet
);
267 bSetScaleData
= true;
270 case SCALE_PROP_AXIS_TYPE
:
273 if( rOuterValue
>>= nType
)
275 if( nType
== css::chart::ChartAxisType::AUTOMATIC
)
277 aScaleData
.AutoDateAxis
= true;
278 if( aScaleData
.AxisType
== AxisType::DATE
)
279 aScaleData
.AxisType
= AxisType::CATEGORY
;
281 else if( nType
== css::chart::ChartAxisType::CATEGORY
)
283 aScaleData
.AutoDateAxis
= false;
284 if( aScaleData
.AxisType
== AxisType::DATE
)
285 aScaleData
.AxisType
= AxisType::CATEGORY
;
287 else if( nType
== css::chart::ChartAxisType::DATE
)
289 if( aScaleData
.AxisType
== AxisType::CATEGORY
)
290 aScaleData
.AxisType
= AxisType::DATE
;
292 bSetScaleData
= true;
296 case SCALE_PROP_DATE_INCREMENT
:
298 TimeIncrement aTimeIncrement
;
299 rOuterValue
>>= aTimeIncrement
;
300 aScaleData
.TimeIncrement
= std::move(aTimeIncrement
);
301 bSetScaleData
= true;
304 case SCALE_PROP_EXPLICIT_DATE_INCREMENT
:
307 case SCALE_PROP_LOGARITHMIC
:
309 if( rOuterValue
>>= bBool
)
311 bool bWasLogarithm
= AxisHelper::isLogarithmic( aScaleData
.Scaling
);
313 // safe comparison between sal_Bool and bool
314 if( (!bBool
) != (!bWasLogarithm
) )
317 aScaleData
.Scaling
= AxisHelper::createLogarithmicScaling( 10.0 );
319 aScaleData
.Scaling
= nullptr;
320 bSetScaleData
= true;
325 case SCALE_PROP_REVERSEDIRECTION
:
327 if( rOuterValue
>>= bBool
)
329 bool bWasReverse
= ( aScaleData
.Orientation
== AxisOrientation_REVERSE
);
330 if( (!bBool
) != (!bWasReverse
) ) // safe comparison between sal_Bool and bool
332 aScaleData
.Orientation
= bBool
? AxisOrientation_REVERSE
: AxisOrientation_MATHEMATICAL
;
333 bSetScaleData
= true;
340 OSL_FAIL("unknown scale property");
346 xAxis
->setScaleData( aScaleData
);
349 Any
WrappedScaleProperty::getPropertyValue( tScaleProperty eScaleProperty
, const Reference
< beans::XPropertySet
>& xInnerPropertySet
) const
351 Any
aRet( m_aOuterValue
);
353 rtl::Reference
< Axis
> xAxis
= dynamic_cast<Axis
*>(xInnerPropertySet
.get());
354 OSL_ENSURE(xAxis
.is(),"need an XAxis");
358 chart2::ScaleData
aScaleData( xAxis
->getScaleData() );
360 ExplicitScaleData aExplicitScale
;
361 ExplicitIncrementData aExplicitIncrement
;
363 switch( eScaleProperty
)
367 aRet
= aScaleData
.Maximum
;
368 if( !aRet
.hasValue() )
370 m_spChart2ModelContact
->getExplicitValuesForAxis(
371 xAxis
, aExplicitScale
, aExplicitIncrement
);
372 aRet
<<= aExplicitScale
.Maximum
;
378 aRet
= aScaleData
.Minimum
;
379 if( !aRet
.hasValue() )
381 m_spChart2ModelContact
->getExplicitValuesForAxis(
382 xAxis
, aExplicitScale
, aExplicitIncrement
);
383 aRet
<<= aExplicitScale
.Minimum
;
388 case SCALE_PROP_STEPMAIN
:
390 aRet
= aScaleData
.IncrementData
.Distance
;
391 if( !aRet
.hasValue() )
393 m_spChart2ModelContact
->getExplicitValuesForAxis(
394 xAxis
, aExplicitScale
, aExplicitIncrement
);
395 aRet
<<= aExplicitIncrement
.Distance
;
399 case SCALE_PROP_STEPHELP
:
401 // todo: evaluate PostEquidistant
402 bool bNeedToCalculateExplicitValues
= true;
404 bool bLogarithmic( AxisHelper::isLogarithmic(aScaleData
.Scaling
) );
405 Sequence
< chart2::SubIncrement
>& rSubIncrements( aScaleData
.IncrementData
.SubIncrements
);
408 if( rSubIncrements
.hasElements() )
410 sal_Int32 nIntervalCount
= 0;
411 rSubIncrements
[ 0 ].IntervalCount
>>= nIntervalCount
;
412 aRet
<<= double(nIntervalCount
);
413 bNeedToCalculateExplicitValues
= false;
416 else if( aScaleData
.IncrementData
.Distance
.hasValue() )
418 if( rSubIncrements
.hasElements() )
420 double fStepMain
= 0;
421 sal_Int32 nIntervalCount
= 0;
422 if( (aScaleData
.IncrementData
.Distance
>>= fStepMain
) &&
423 (rSubIncrements
[ 0 ].IntervalCount
>>= nIntervalCount
) &&
426 aRet
<<= fStepMain
/ static_cast< double >( nIntervalCount
);
427 bNeedToCalculateExplicitValues
= false;
432 aRet
= aScaleData
.IncrementData
.Distance
;
433 bNeedToCalculateExplicitValues
= false;
437 if( bNeedToCalculateExplicitValues
)
439 m_spChart2ModelContact
->getExplicitValuesForAxis(
440 xAxis
, aExplicitScale
, aExplicitIncrement
);
442 if( !aExplicitIncrement
.SubIncrements
.empty() &&
443 aExplicitIncrement
.SubIncrements
[ 0 ].IntervalCount
> 0 )
447 if( rSubIncrements
.hasElements() )
449 sal_Int32 nIntervalCount
= aExplicitIncrement
.SubIncrements
[ 0 ].IntervalCount
;
450 aRet
<<= double(nIntervalCount
);
454 aRet
<<= aExplicitIncrement
.Distance
/
455 static_cast< double >(
456 aExplicitIncrement
.SubIncrements
[ 0 ].IntervalCount
);
463 aRet
<<= aExplicitIncrement
.Distance
;
468 case SCALE_PROP_STEPHELP_COUNT
:
470 sal_Int32 nIntervalCount
= 0;
471 bool bNeedToCalculateExplicitValues
= true;
472 Sequence
< chart2::SubIncrement
>& rSubIncrements( aScaleData
.IncrementData
.SubIncrements
);
473 if( rSubIncrements
.hasElements() )
475 if( (rSubIncrements
[ 0 ].IntervalCount
>>= nIntervalCount
) && (nIntervalCount
> 0) )
476 bNeedToCalculateExplicitValues
= false;
478 if( bNeedToCalculateExplicitValues
)
480 m_spChart2ModelContact
->getExplicitValuesForAxis( xAxis
, aExplicitScale
, aExplicitIncrement
);
481 if( !aExplicitIncrement
.SubIncrements
.empty() )
482 nIntervalCount
= aExplicitIncrement
.SubIncrements
[ 0 ].IntervalCount
;
484 aRet
<<= nIntervalCount
;
487 case SCALE_PROP_AUTO_MAX
:
489 aRet
<<= !aScaleData
.Maximum
.hasValue();
492 case SCALE_PROP_AUTO_MIN
:
494 aRet
<<= !aScaleData
.Minimum
.hasValue();
497 case SCALE_PROP_AUTO_STEPMAIN
:
499 aRet
<<= !aScaleData
.IncrementData
.Distance
.hasValue();
502 case SCALE_PROP_AUTO_STEPHELP
:
504 Sequence
< chart2::SubIncrement
>& rSubIncrements( aScaleData
.IncrementData
.SubIncrements
);
505 if( rSubIncrements
.hasElements() )
506 aRet
<<= !rSubIncrements
[ 0 ].IntervalCount
.hasValue();
511 case SCALE_PROP_ORIGIN
:
513 aRet
= aScaleData
.Origin
;
514 if( !aRet
.hasValue() )
516 m_spChart2ModelContact
->getExplicitValuesForAxis(
517 xAxis
, aExplicitScale
, aExplicitIncrement
);
518 aRet
<<= aExplicitScale
.Origin
;
522 case SCALE_PROP_AUTO_ORIGIN
:
524 aRet
<<= !hasDoubleValue(aScaleData
.Origin
);
527 case SCALE_PROP_AXIS_TYPE
:
529 sal_Int32 nType
= css::chart::ChartAxisType::AUTOMATIC
;
530 if( aScaleData
.AxisType
== AxisType::DATE
)
532 nType
= css::chart::ChartAxisType::DATE
;
534 else if( aScaleData
.AxisType
== AxisType::CATEGORY
)
536 if( !aScaleData
.AutoDateAxis
)
537 nType
= css::chart::ChartAxisType::CATEGORY
;
542 case SCALE_PROP_DATE_INCREMENT
:
544 if( aScaleData
.AxisType
== AxisType::DATE
|| aScaleData
.AutoDateAxis
)
545 aRet
<<= aScaleData
.TimeIncrement
;
548 case SCALE_PROP_EXPLICIT_DATE_INCREMENT
:
550 if( aScaleData
.AxisType
== AxisType::DATE
|| aScaleData
.AutoDateAxis
)
552 m_spChart2ModelContact
->getExplicitValuesForAxis( xAxis
, aExplicitScale
, aExplicitIncrement
);
553 if( aExplicitScale
.AxisType
== AxisType::DATE
)
555 TimeIncrement aTimeIncrement
;
556 aTimeIncrement
.MajorTimeInterval
<<= aExplicitIncrement
.MajorTimeInterval
;
557 aTimeIncrement
.MinorTimeInterval
<<= aExplicitIncrement
.MinorTimeInterval
;
558 aTimeIncrement
.TimeResolution
<<= aExplicitScale
.TimeResolution
;
559 aRet
<<= aTimeIncrement
;
562 aRet
<<= aScaleData
.TimeIncrement
;
567 case SCALE_PROP_LOGARITHMIC
:
569 aRet
<<= AxisHelper::isLogarithmic(aScaleData
.Scaling
);
572 case SCALE_PROP_REVERSEDIRECTION
:
574 aRet
<<= aScaleData
.Orientation
== AxisOrientation_REVERSE
;
579 OSL_FAIL("unknown scale property");
589 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */