cid#1640468 Dereference after null check
[LibreOffice.git] / chart2 / source / controller / chartapiwrapper / WrappedScaleProperty.cxx
blob35b8cd3040eac5a2a3285bd4921d6298e50a3b4e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
23 #include <Axis.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>
29 #include <utility>
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 )
50 case SCALE_PROP_MAX:
51 m_aOuterName = "Max";
52 break;
53 case SCALE_PROP_MIN:
54 m_aOuterName = "Min";
55 break;
56 case SCALE_PROP_ORIGIN:
57 m_aOuterName = "Origin";
58 break;
59 case SCALE_PROP_STEPMAIN:
60 m_aOuterName = "StepMain";
61 break;
62 case SCALE_PROP_STEPHELP:
63 m_aOuterName = "StepHelp";
64 break;
65 case SCALE_PROP_STEPHELP_COUNT:
66 m_aOuterName = "StepHelpCount";
67 break;
68 case SCALE_PROP_AUTO_MAX:
69 m_aOuterName = "AutoMax";
70 break;
71 case SCALE_PROP_AUTO_MIN:
72 m_aOuterName = "AutoMin";
73 break;
74 case SCALE_PROP_AUTO_ORIGIN:
75 m_aOuterName = "AutoOrigin";
76 break;
77 case SCALE_PROP_AUTO_STEPMAIN:
78 m_aOuterName = "AutoStepMain";
79 break;
80 case SCALE_PROP_AUTO_STEPHELP:
81 m_aOuterName = "AutoStepHelp";
82 break;
83 case SCALE_PROP_AXIS_TYPE:
84 m_aOuterName = "AxisType";
85 break;
86 case SCALE_PROP_DATE_INCREMENT:
87 m_aOuterName = "TimeIncrement";
88 break;
89 case SCALE_PROP_EXPLICIT_DATE_INCREMENT:
90 m_aOuterName = "ExplicitTimeIncrement";
91 break;
92 case SCALE_PROP_LOGARITHMIC:
93 m_aOuterName = "Logarithmic";
94 break;
95 case SCALE_PROP_REVERSEDIRECTION:
96 m_aOuterName = "ReverseDirection";
97 break;
98 default:
99 OSL_FAIL("unknown scale property");
100 break;
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");
145 if(!xAxis.is())
146 return;
148 bool bSetScaleData = false;
150 chart2::ScaleData aScaleData( xAxis->getScaleData() );
152 bool bBool = false;
153 switch( eScaleProperty )
155 case SCALE_PROP_MAX:
157 aScaleData.Maximum = rOuterValue;
158 bSetScaleData = true;
159 break;
161 case SCALE_PROP_MIN:
163 aScaleData.Minimum = rOuterValue;
164 bSetScaleData = true;
165 break;
167 case SCALE_PROP_STEPMAIN:
169 aScaleData.IncrementData.Distance = rOuterValue;
170 bSetScaleData = true;
171 break;
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;
198 break;
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;
209 else
210 pSubIncrements[ 0 ].IntervalCount = Any();
211 bSetScaleData = true;
212 break;
214 case SCALE_PROP_AUTO_MAX:
216 if( (rOuterValue >>= bBool) && bBool )
217 aScaleData.Maximum = Any();
218 else
219 aScaleData.Maximum = getPropertyValue( SCALE_PROP_MAX, xInnerPropertySet );
220 bSetScaleData = true;
221 break;
223 case SCALE_PROP_AUTO_MIN:
225 if( (rOuterValue >>= bBool) && bBool )
226 aScaleData.Minimum = Any();
227 else
228 aScaleData.Minimum = getPropertyValue( SCALE_PROP_MIN, xInnerPropertySet );
229 bSetScaleData = true;
230 break;
232 case SCALE_PROP_AUTO_STEPMAIN:
234 if( (rOuterValue >>= bBool) && bBool )
235 aScaleData.IncrementData.Distance = Any();
236 else
237 aScaleData.IncrementData.Distance = getPropertyValue( SCALE_PROP_STEPMAIN, xInnerPropertySet );
238 bSetScaleData = true;
239 break;
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();
250 else
251 pSubIncrements[ 0 ].IntervalCount = getPropertyValue( SCALE_PROP_STEPHELP_COUNT, xInnerPropertySet );
252 bSetScaleData = true;
253 break;
255 case SCALE_PROP_ORIGIN:
257 aScaleData.Origin = rOuterValue;
258 bSetScaleData = true;
259 break;
261 case SCALE_PROP_AUTO_ORIGIN:
263 if( (rOuterValue >>= bBool) && bBool )
264 aScaleData.Origin = Any();
265 else
266 aScaleData.Origin = getPropertyValue( SCALE_PROP_ORIGIN, xInnerPropertySet );
267 bSetScaleData = true;
268 break;
270 case SCALE_PROP_AXIS_TYPE:
272 sal_Int32 nType = 0;
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;
294 break;
296 case SCALE_PROP_DATE_INCREMENT:
298 TimeIncrement aTimeIncrement;
299 rOuterValue >>= aTimeIncrement;
300 aScaleData.TimeIncrement = std::move(aTimeIncrement);
301 bSetScaleData = true;
302 break;
304 case SCALE_PROP_EXPLICIT_DATE_INCREMENT:
305 //read only property
306 break;
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) )
316 if( bBool )
317 aScaleData.Scaling = AxisHelper::createLogarithmicScaling( 10.0 );
318 else
319 aScaleData.Scaling = nullptr;
320 bSetScaleData = true;
323 break;
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;
336 break;
338 default:
340 OSL_FAIL("unknown scale property");
341 break;
345 if( bSetScaleData )
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");
355 if(!xAxis.is())
356 return aRet;
358 chart2::ScaleData aScaleData( xAxis->getScaleData() );
360 ExplicitScaleData aExplicitScale;
361 ExplicitIncrementData aExplicitIncrement;
363 switch( eScaleProperty )
365 case SCALE_PROP_MAX:
367 aRet = aScaleData.Maximum;
368 if( !aRet.hasValue() )
370 m_spChart2ModelContact->getExplicitValuesForAxis(
371 xAxis, aExplicitScale, aExplicitIncrement );
372 aRet <<= aExplicitScale.Maximum;
374 break;
376 case SCALE_PROP_MIN:
378 aRet = aScaleData.Minimum;
379 if( !aRet.hasValue() )
381 m_spChart2ModelContact->getExplicitValuesForAxis(
382 xAxis, aExplicitScale, aExplicitIncrement );
383 aRet <<= aExplicitScale.Minimum;
385 break;
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;
397 break;
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 );
406 if( bLogarithmic )
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) &&
424 nIntervalCount > 0 )
426 aRet <<= fStepMain / static_cast< double >( nIntervalCount );
427 bNeedToCalculateExplicitValues = false;
430 else
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 )
445 if( bLogarithmic )
447 if( rSubIncrements.hasElements() )
449 sal_Int32 nIntervalCount = aExplicitIncrement.SubIncrements[ 0 ].IntervalCount;
450 aRet <<= double(nIntervalCount);
453 else
454 aRet <<= aExplicitIncrement.Distance /
455 static_cast< double >(
456 aExplicitIncrement.SubIncrements[ 0 ].IntervalCount );
458 else
460 if( bLogarithmic )
461 aRet <<= 5.0;
462 else
463 aRet <<= aExplicitIncrement.Distance;
466 break;
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;
485 break;
487 case SCALE_PROP_AUTO_MAX:
489 aRet <<= !aScaleData.Maximum.hasValue();
490 break;
492 case SCALE_PROP_AUTO_MIN:
494 aRet <<= !aScaleData.Minimum.hasValue();
495 break;
497 case SCALE_PROP_AUTO_STEPMAIN:
499 aRet <<= !aScaleData.IncrementData.Distance.hasValue();
500 break;
502 case SCALE_PROP_AUTO_STEPHELP:
504 Sequence< chart2::SubIncrement >& rSubIncrements( aScaleData.IncrementData.SubIncrements );
505 if( rSubIncrements.hasElements() )
506 aRet <<= !rSubIncrements[ 0 ].IntervalCount.hasValue();
507 else
508 aRet <<= true;
509 break;
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;
520 break;
522 case SCALE_PROP_AUTO_ORIGIN:
524 aRet <<= !hasDoubleValue(aScaleData.Origin);
525 break;
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;
539 aRet <<= nType;
540 break;
542 case SCALE_PROP_DATE_INCREMENT:
544 if( aScaleData.AxisType == AxisType::DATE || aScaleData.AutoDateAxis )
545 aRet <<= aScaleData.TimeIncrement;
546 break;
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;
561 else
562 aRet <<= aScaleData.TimeIncrement;
565 break;
567 case SCALE_PROP_LOGARITHMIC:
569 aRet <<= AxisHelper::isLogarithmic(aScaleData.Scaling);
570 break;
572 case SCALE_PROP_REVERSEDIRECTION:
574 aRet <<= aScaleData.Orientation == AxisOrientation_REVERSE;
575 break;
577 default:
579 OSL_FAIL("unknown scale property");
580 break;
584 return aRet;
587 } // namespace chart
589 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */