Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / chart2 / source / controller / itemsetwrapper / ErrorBarItemConverter.cxx
blob1374c4c4f2c71a2c1d14e40127970f4fc2457ede
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 <ErrorBarItemConverter.hxx>
21 #include "SchWhichPairs.hxx"
22 #include <ItemPropertyMap.hxx>
23 #include <ErrorBar.hxx>
24 #include <PropertyHelper.hxx>
25 #include <ChartModelHelper.hxx>
26 #include <ChartTypeHelper.hxx>
27 #include <StatisticsHelper.hxx>
29 #include <GraphicPropertyItemConverter.hxx>
31 #include <svl/stritem.hxx>
32 #include <svx/chrtitem.hxx>
33 #include <svl/intitem.hxx>
34 #include <rtl/math.hxx>
36 #include <com/sun/star/chart2/DataPointLabel.hpp>
37 #include <com/sun/star/chart2/XInternalDataProvider.hpp>
38 #include <com/sun/star/chart/ErrorBarStyle.hpp>
39 #include <com/sun/star/lang/XServiceName.hpp>
40 #include <tools/diagnose_ex.h>
42 #include <functional>
43 #include <algorithm>
44 #include <vector>
46 using namespace ::com::sun::star;
48 namespace
51 void lcl_getErrorValues( const uno::Reference< beans::XPropertySet > & xErrorBarProp,
52 double & rOutPosError, double & rOutNegError )
54 if( ! xErrorBarProp.is())
55 return;
57 try
59 xErrorBarProp->getPropertyValue( "PositiveError" ) >>= rOutPosError;
60 xErrorBarProp->getPropertyValue( "NegativeError" ) >>= rOutNegError;
62 catch( const uno::Exception & )
64 DBG_UNHANDLED_EXCEPTION("chart2");
68 void lcl_getErrorIndicatorValues(
69 const uno::Reference< beans::XPropertySet > & xErrorBarProp,
70 bool & rOutShowPosError, bool & rOutShowNegError )
72 if( ! xErrorBarProp.is())
73 return;
75 try
77 xErrorBarProp->getPropertyValue( "ShowPositiveError" ) >>= rOutShowPosError;
78 xErrorBarProp->getPropertyValue( "ShowNegativeError" ) >>= rOutShowNegError;
80 catch( const uno::Exception & )
82 DBG_UNHANDLED_EXCEPTION("chart2");
86 } // anonymous namespace
88 namespace chart
90 namespace wrapper
93 ErrorBarItemConverter::ErrorBarItemConverter(
94 const uno::Reference< frame::XModel > & xModel,
95 const uno::Reference< beans::XPropertySet > & rPropertySet,
96 SfxItemPool& rItemPool,
97 SdrModel& rDrawModel,
98 const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory ) :
99 ItemConverter( rPropertySet, rItemPool ),
100 m_spGraphicConverter( new GraphicPropertyItemConverter(
101 rPropertySet, rItemPool, rDrawModel,
102 xNamedPropertyContainerFactory,
103 GraphicObjectType::LineProperties )),
104 m_xModel( xModel )
107 ErrorBarItemConverter::~ErrorBarItemConverter()
110 void ErrorBarItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const
112 m_spGraphicConverter->FillItemSet( rOutItemSet );
114 // own items
115 ItemConverter::FillItemSet( rOutItemSet );
118 bool ErrorBarItemConverter::ApplyItemSet( const SfxItemSet & rItemSet )
120 bool bResult = m_spGraphicConverter->ApplyItemSet( rItemSet );
122 // own items
123 return ItemConverter::ApplyItemSet( rItemSet ) || bResult;
126 const sal_uInt16 * ErrorBarItemConverter::GetWhichPairs() const
128 // must span all used items!
129 return nErrorBarWhichPairs;
132 bool ErrorBarItemConverter::GetItemProperty(
133 tWhichIdType /* nWhichId */,
134 tPropertyNameWithMemberId & /* rOutProperty */ ) const
136 return false;
139 bool ErrorBarItemConverter::ApplySpecialItem(
140 sal_uInt16 nWhichId, const SfxItemSet & rItemSet )
142 bool bChanged = false;
144 switch( nWhichId )
146 // Attention !!! This case must be passed before SCHATTR_STAT_PERCENT,
147 // SCHATTR_STAT_BIGERROR, SCHATTR_STAT_CONSTPLUS,
148 // SCHATTR_STAT_CONSTMINUS and SCHATTR_STAT_INDICATE
149 case SCHATTR_STAT_KIND_ERROR:
151 uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet());
153 SvxChartKindError eErrorKind =
154 static_cast< const SvxChartKindErrorItem & >(
155 rItemSet.Get( nWhichId )).GetValue();
157 if( !xErrorBarProp.is() && eErrorKind == SvxChartKindError::NONE)
159 //nothing to do
161 else
163 sal_Int32 nStyle = css::chart::ErrorBarStyle::NONE;
165 switch( eErrorKind )
167 case SvxChartKindError::NONE:
168 nStyle = css::chart::ErrorBarStyle::NONE; break;
169 case SvxChartKindError::Variant:
170 nStyle = css::chart::ErrorBarStyle::VARIANCE; break;
171 case SvxChartKindError::Sigma:
172 nStyle = css::chart::ErrorBarStyle::STANDARD_DEVIATION; break;
173 case SvxChartKindError::Percent:
174 nStyle = css::chart::ErrorBarStyle::RELATIVE; break;
175 case SvxChartKindError::BigError:
176 nStyle = css::chart::ErrorBarStyle::ERROR_MARGIN; break;
177 case SvxChartKindError::Const:
178 nStyle = css::chart::ErrorBarStyle::ABSOLUTE; break;
179 case SvxChartKindError::StdError:
180 nStyle = css::chart::ErrorBarStyle::STANDARD_ERROR; break;
181 case SvxChartKindError::Range:
182 nStyle = css::chart::ErrorBarStyle::FROM_DATA; break;
185 xErrorBarProp->setPropertyValue( "ErrorBarStyle" , uno::Any( nStyle ));
186 bChanged = true;
189 break;
191 case SCHATTR_STAT_PERCENT:
192 case SCHATTR_STAT_BIGERROR:
194 OSL_FAIL( "Deprecated item" );
195 uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet());
197 double fValue =
198 static_cast< const SvxDoubleItem & >(
199 rItemSet.Get( nWhichId )).GetValue();
200 double fPos(0.0), fNeg(0.0);
201 lcl_getErrorValues( xErrorBarProp, fPos, fNeg );
203 if( ! ( ::rtl::math::approxEqual( fPos, fValue ) &&
204 ::rtl::math::approxEqual( fNeg, fValue )))
206 xErrorBarProp->setPropertyValue( "PositiveError" , uno::Any( fValue ));
207 xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue ));
208 bChanged = true;
211 break;
213 case SCHATTR_STAT_CONSTPLUS:
215 double fValue =
216 static_cast< const SvxDoubleItem & >(
217 rItemSet.Get( nWhichId )).GetValue();
218 double fPos(0.0), fNeg(0.0);
219 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
221 if( ! ::rtl::math::approxEqual( fPos, fValue ))
223 GetPropertySet()->setPropertyValue( "PositiveError" , uno::Any( fValue ));
224 bChanged = true;
227 break;
229 case SCHATTR_STAT_CONSTMINUS:
231 uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet());
233 double fValue =
234 static_cast< const SvxDoubleItem & >(
235 rItemSet.Get( nWhichId )).GetValue();
236 double fPos(0.0), fNeg(0.0);
237 lcl_getErrorValues( xErrorBarProp, fPos, fNeg );
239 if( ! ::rtl::math::approxEqual( fNeg, fValue ))
241 xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue ));
242 bChanged = true;
245 break;
247 case SCHATTR_STAT_INDICATE:
249 uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet());
251 SvxChartIndicate eIndicate =
252 static_cast< const SvxChartIndicateItem & >(
253 rItemSet.Get( nWhichId )).GetValue();
255 bool bNewIndPos = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Up );
256 bool bNewIndNeg = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Down );
258 bool bShowPos(false), bShowNeg(false);
259 lcl_getErrorIndicatorValues( xErrorBarProp, bShowPos, bShowNeg );
261 if( bShowPos != bNewIndPos ||
262 bShowNeg != bNewIndNeg )
264 xErrorBarProp->setPropertyValue( "ShowPositiveError" , uno::Any( bNewIndPos ));
265 xErrorBarProp->setPropertyValue( "ShowNegativeError" , uno::Any( bNewIndNeg ));
266 bChanged = true;
269 break;
271 case SCHATTR_STAT_RANGE_POS:
272 case SCHATTR_STAT_RANGE_NEG:
274 // @todo: also be able to deal with x-error bars
275 const bool bYError =
276 rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue();
278 uno::Reference< chart2::data::XDataSource > xErrorBarSource( GetPropertySet(), uno::UNO_QUERY );
279 uno::Reference< chart2::XChartDocument > xChartDoc( m_xModel, uno::UNO_QUERY );
280 uno::Reference< chart2::data::XDataProvider > xDataProvider;
282 if( xChartDoc.is())
283 xDataProvider.set( xChartDoc->getDataProvider());
284 if( xErrorBarSource.is() && xDataProvider.is())
286 OUString aNewRange( static_cast< const SfxStringItem & >( rItemSet.Get( nWhichId )).GetValue());
287 bool bApplyNewRange = false;
289 bool bIsPositiveValue( nWhichId == SCHATTR_STAT_RANGE_POS );
290 if( xChartDoc->hasInternalDataProvider())
292 if( !aNewRange.isEmpty())
294 uno::Reference< chart2::data::XDataSequence > xSeq(
295 StatisticsHelper::getErrorDataSequenceFromDataSource(
296 xErrorBarSource, bIsPositiveValue, bYError ));
297 if( ! xSeq.is())
299 // no data range for error bars yet => create
300 uno::Reference< chart2::XInternalDataProvider > xIntDataProvider( xDataProvider, uno::UNO_QUERY );
301 OSL_ASSERT( xIntDataProvider.is());
302 if( xIntDataProvider.is())
304 xIntDataProvider->appendSequence();
305 aNewRange = "last";
306 bApplyNewRange = true;
311 else
313 uno::Reference< chart2::data::XDataSequence > xSeq(
314 StatisticsHelper::getErrorDataSequenceFromDataSource(
315 xErrorBarSource, bIsPositiveValue, bYError ));
316 bApplyNewRange =
317 ! ( xSeq.is() && (aNewRange == xSeq->getSourceRangeRepresentation()));
320 if( bApplyNewRange )
321 StatisticsHelper::setErrorDataSequence(
322 xErrorBarSource, xDataProvider, aNewRange, bIsPositiveValue, bYError );
325 break;
328 return bChanged;
331 void ErrorBarItemConverter::FillSpecialItem(
332 sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const
334 switch( nWhichId )
336 case SCHATTR_STAT_KIND_ERROR:
338 SvxChartKindError eErrorKind = SvxChartKindError::NONE;
339 uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet());
341 sal_Int32 nStyle = 0;
342 if( xErrorBarProp->getPropertyValue( "ErrorBarStyle" ) >>= nStyle )
344 switch( nStyle )
346 case css::chart::ErrorBarStyle::NONE:
347 break;
348 case css::chart::ErrorBarStyle::VARIANCE:
349 eErrorKind = SvxChartKindError::Variant; break;
350 case css::chart::ErrorBarStyle::STANDARD_DEVIATION:
351 eErrorKind = SvxChartKindError::Sigma; break;
352 case css::chart::ErrorBarStyle::ABSOLUTE:
353 eErrorKind = SvxChartKindError::Const; break;
354 case css::chart::ErrorBarStyle::RELATIVE:
355 eErrorKind = SvxChartKindError::Percent; break;
356 case css::chart::ErrorBarStyle::ERROR_MARGIN:
357 eErrorKind = SvxChartKindError::BigError; break;
358 case css::chart::ErrorBarStyle::STANDARD_ERROR:
359 eErrorKind = SvxChartKindError::StdError; break;
360 case css::chart::ErrorBarStyle::FROM_DATA:
361 eErrorKind = SvxChartKindError::Range; break;
364 rOutItemSet.Put( SvxChartKindErrorItem( eErrorKind, SCHATTR_STAT_KIND_ERROR ));
366 break;
368 case SCHATTR_STAT_PERCENT:
370 double fPos(0.0), fNeg(0.0);
371 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
372 rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, nWhichId ));
374 break;
376 case SCHATTR_STAT_BIGERROR:
378 double fPos(0.0), fNeg(0.0);
379 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
380 rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, nWhichId ));
382 break;
384 case SCHATTR_STAT_CONSTPLUS:
386 double fPos(0.0), fNeg(0.0);
387 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
388 rOutItemSet.Put( SvxDoubleItem( fPos, nWhichId ));
390 break;
392 case SCHATTR_STAT_CONSTMINUS:
394 double fPos(0.0), fNeg(0.0);
395 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
396 rOutItemSet.Put( SvxDoubleItem( fNeg, nWhichId ));
398 break;
400 case SCHATTR_STAT_INDICATE:
402 SvxChartIndicate eIndicate = SvxChartIndicate::Both;
403 bool bShowPos(false), bShowNeg(false);
404 lcl_getErrorIndicatorValues( GetPropertySet(), bShowPos, bShowNeg );
406 if( bShowPos )
408 if( bShowNeg )
409 eIndicate = SvxChartIndicate::Both;
410 else
411 eIndicate = SvxChartIndicate::Up;
413 else
415 if( bShowNeg )
416 eIndicate = SvxChartIndicate::Down;
417 else
418 eIndicate = SvxChartIndicate::NONE;
420 rOutItemSet.Put( SvxChartIndicateItem( eIndicate, SCHATTR_STAT_INDICATE ));
422 break;
424 case SCHATTR_STAT_RANGE_POS:
425 case SCHATTR_STAT_RANGE_NEG:
427 const bool bYError =
428 rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue();
430 uno::Reference< chart2::data::XDataSource > xErrorBarSource( GetPropertySet(), uno::UNO_QUERY );
431 if( xErrorBarSource.is())
433 uno::Reference< chart2::data::XDataSequence > xSeq(
434 StatisticsHelper::getErrorDataSequenceFromDataSource(
435 xErrorBarSource, (nWhichId == SCHATTR_STAT_RANGE_POS), bYError ));
436 if( xSeq.is())
437 rOutItemSet.Put( SfxStringItem( nWhichId, xSeq->getSourceRangeRepresentation()));
440 break;
444 } // namespace wrapper
445 } // namespace chart
447 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */