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 <ErrorBar.hxx>
21 #include <EventListenerHelper.hxx>
22 #include <CloneHelper.hxx>
23 #include <ModifyListenerHelper.hxx>
25 #include <comphelper/sequence.hxx>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <svl/itemprop.hxx>
28 #include <vcl/svapp.hxx>
30 #include <com/sun/star/chart/ErrorBarStyle.hpp>
32 #include <com/sun/star/drawing/LineStyle.hpp>
33 #include <com/sun/star/util/Color.hpp>
34 #include <com/sun/star/drawing/LineJoint.hpp>
36 #include <comphelper/diagnose_ex.hxx>
37 #include <sal/log.hxx>
39 using namespace ::com::sun::star
;
44 constexpr OUString lcl_aServiceName
= u
"com.sun.star.comp.chart2.ErrorBar"_ustr
;
46 bool lcl_isInternalData( const uno::Reference
< chart2::data::XLabeledDataSequence
> & xLSeq
)
48 uno::Reference
< lang::XServiceInfo
> xServiceInfo( xLSeq
, uno::UNO_QUERY
);
49 return ( xServiceInfo
.is() && xServiceInfo
->getImplementationName() == "com.sun.star.comp.chart2.LabeledDataSequence" );
52 const SfxItemPropertySet
* GetErrorBarPropertySet()
54 static const SfxItemPropertyMapEntry aErrorBarPropertyMap_Impl
[] =
56 {u
"ShowPositiveError"_ustr
,0,cppu::UnoType
<bool>::get(), 0, 0},
57 {u
"ShowNegativeError"_ustr
,1,cppu::UnoType
<bool>::get(), 0, 0},
58 {u
"PositiveError"_ustr
,2,cppu::UnoType
<double>::get(),0,0},
59 {u
"NegativeError"_ustr
,3,cppu::UnoType
<double>::get(), 0, 0},
60 {u
"PercentageError"_ustr
,4,cppu::UnoType
<double>::get(), 0, 0},
61 {u
"ErrorBarStyle"_ustr
,5,cppu::UnoType
<sal_Int32
>::get(),0,0},
62 {u
"ErrorBarRangePositive"_ustr
,6,cppu::UnoType
<OUString
>::get(),0,0}, // read-only for export
63 {u
"ErrorBarRangeNegative"_ustr
,7,cppu::UnoType
<OUString
>::get(),0,0}, // read-only for export
64 {u
"Weight"_ustr
,8,cppu::UnoType
<double>::get(),0,0},
65 {u
"LineStyle"_ustr
,9,cppu::UnoType
<css::drawing::LineStyle
>::get(),0,0},
66 {u
"LineDash"_ustr
,10,cppu::UnoType
<drawing::LineDash
>::get(),0,0},
67 {u
"LineWidth"_ustr
,11,cppu::UnoType
<sal_Int32
>::get(),0,0},
68 {u
"LineColor"_ustr
,12,cppu::UnoType
<css::util::Color
>::get(),0,0},
69 {u
"LineTransparence"_ustr
,13,cppu::UnoType
<sal_Int16
>::get(),0,0},
70 {u
"LineJoint"_ustr
,14,cppu::UnoType
<css::drawing::LineJoint
>::get(),0,0},
72 static SfxItemPropertySet
aPropSet( aErrorBarPropertyMap_Impl
);
76 } // anonymous namespace
81 ErrorBar::ErrorBar() :
83 meLineStyle(drawing::LineStyle_SOLID
),
85 mnLineTransparence(0),
86 meLineJoint(drawing::LineJoint_ROUND
),
87 mbShowPositiveError(true),
88 mbShowNegativeError(true),
92 meStyle(css::chart::ErrorBarStyle::NONE
),
93 m_xModifyEventForwarder( new ModifyEventForwarder() )
96 ErrorBar::ErrorBar( const ErrorBar
& rOther
) :
97 impl::ErrorBar_Base(rOther
),
98 maDashName(rOther
.maDashName
),
99 maLineDash(rOther
.maLineDash
),
100 mnLineWidth(rOther
.mnLineWidth
),
101 meLineStyle(rOther
.meLineStyle
),
102 maLineColor(rOther
.maLineColor
),
103 mnLineTransparence(rOther
.mnLineTransparence
),
104 meLineJoint(rOther
.meLineJoint
),
105 mbShowPositiveError(rOther
.mbShowPositiveError
),
106 mbShowNegativeError(rOther
.mbShowNegativeError
),
107 mfPositiveError(rOther
.mfPositiveError
),
108 mfNegativeError(rOther
.mfNegativeError
),
109 mfWeight(rOther
.mfWeight
),
110 meStyle(rOther
.meStyle
),
111 m_xModifyEventForwarder( new ModifyEventForwarder() )
113 if( ! rOther
.m_aDataSequences
.empty())
115 if( lcl_isInternalData( rOther
.m_aDataSequences
.front()))
116 CloneHelper::CloneRefVector
< css::chart2::data::XLabeledDataSequence
>(
117 rOther
.m_aDataSequences
, m_aDataSequences
);
119 m_aDataSequences
= rOther
.m_aDataSequences
;
120 ModifyListenerHelper::addListenerToAllElements( m_aDataSequences
, m_xModifyEventForwarder
);
124 ErrorBar::~ErrorBar()
127 uno::Reference
< util::XCloneable
> SAL_CALL
ErrorBar::createClone()
129 return uno::Reference
< util::XCloneable
>( new ErrorBar( *this ));
132 // ____ XPropertySet ____
133 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
ErrorBar::getPropertySetInfo()
135 static uno::Reference
< beans::XPropertySetInfo
> aRef (
136 new SfxItemPropertySetInfo( GetErrorBarPropertySet()->getPropertyMap() ) );
140 void ErrorBar::setPropertyValue( const OUString
& rPropName
, const uno::Any
& rAny
)
142 SolarMutexGuard aGuard
;
144 if(rPropName
== "ErrorBarStyle")
146 else if(rPropName
== "PositiveError")
147 rAny
>>= mfPositiveError
;
148 else if(rPropName
== "PercentageError")
150 rAny
>>= mfPositiveError
;
151 rAny
>>= mfNegativeError
;
153 else if(rPropName
== "Weight")
157 else if(rPropName
== "NegativeError")
158 rAny
>>= mfNegativeError
;
159 else if(rPropName
== "ShowPositiveError")
160 rAny
>>= mbShowPositiveError
;
161 else if(rPropName
== "ShowNegativeError")
162 rAny
>>= mbShowNegativeError
;
163 else if(rPropName
== "ErrorBarRangePositive" || rPropName
== "ErrorBarRangeNegative")
164 throw beans::UnknownPropertyException("read-only property", static_cast< uno::XWeak
*>(this));
165 else if(rPropName
== "LineDashName")
167 else if(rPropName
== "LineDash")
169 else if(rPropName
== "LineWidth")
170 rAny
>>= mnLineWidth
;
171 else if(rPropName
== "LineStyle")
172 rAny
>>= meLineStyle
;
173 else if(rPropName
== "LineColor")
174 rAny
>>= maLineColor
;
175 else if(rPropName
== "LineTransparence")
176 rAny
>>= mnLineTransparence
;
177 else if(rPropName
== "LineJoint")
178 rAny
>>= meLineJoint
;
180 m_xModifyEventForwarder
->modified( lang::EventObject( static_cast< uno::XWeak
* >( this )));
185 OUString
getSourceRangeStrFromLabeledSequences( const uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> >& aSequences
, bool bPositive
)
189 aDirection
= "positive";
191 aDirection
= "negative";
193 for( uno::Reference
< chart2::data::XLabeledDataSequence
> const & labeledData
: aSequences
)
197 if( labeledData
.is())
199 uno::Reference
< chart2::data::XDataSequence
> xSequence( labeledData
->getValues());
200 uno::Reference
< beans::XPropertySet
> xSeqProp( xSequence
, uno::UNO_QUERY_THROW
);
202 if( ( xSeqProp
->getPropertyValue( "Role" ) >>= aRole
) &&
203 aRole
.match( "error-bars" ) && aRole
.indexOf(aDirection
) >= 0 )
205 return xSequence
->getSourceRangeRepresentation();
209 catch (uno::Exception
const &)
211 // we can't be sure that this is 100% safe and we don't want to kill the export
212 // we should at least check why the exception is thrown
213 TOOLS_WARN_EXCEPTION("chart2", "unexpected exception");
217 // we can't be sure that this is 100% safe and we don't want to kill the export
218 // we should at least check why the exception is thrown
219 SAL_WARN("chart2", "unexpected exception! ");
228 uno::Any
ErrorBar::getPropertyValue(const OUString
& rPropName
)
230 SolarMutexGuard aGuard
;
233 if(rPropName
== "ErrorBarStyle")
235 else if(rPropName
== "PositiveError")
236 aRet
<<= mfPositiveError
;
237 else if(rPropName
== "NegativeError")
238 aRet
<<= mfNegativeError
;
239 else if(rPropName
== "PercentageError")
240 aRet
<<= mfPositiveError
;
241 else if(rPropName
== "ShowPositiveError")
242 aRet
<<= mbShowPositiveError
;
243 else if(rPropName
== "ShowNegativeError")
244 aRet
<<= mbShowNegativeError
;
245 else if(rPropName
== "Weight")
247 else if(rPropName
== "ErrorBarRangePositive")
250 if(meStyle
== css::chart::ErrorBarStyle::FROM_DATA
)
252 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSequences
=
255 aRange
= getSourceRangeStrFromLabeledSequences( aSequences
, true );
260 else if(rPropName
== "ErrorBarRangeNegative")
263 if(meStyle
== css::chart::ErrorBarStyle::FROM_DATA
)
265 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSequences
=
268 aRange
= getSourceRangeStrFromLabeledSequences( aSequences
, false );
273 else if(rPropName
== "LineDashName")
275 else if(rPropName
== "LineDash")
277 else if(rPropName
== "LineWidth")
278 aRet
<<= mnLineWidth
;
279 else if(rPropName
== "LineStyle")
280 aRet
<<= meLineStyle
;
281 else if(rPropName
== "LineColor")
282 aRet
<<= maLineColor
;
283 else if(rPropName
== "LineTransparence")
284 aRet
<<= mnLineTransparence
;
285 else if(rPropName
== "LineJoint")
286 aRet
<<= meLineJoint
;
288 SAL_WARN_IF(!aRet
.hasValue(), "chart2", "asked for property value: " << rPropName
);
292 beans::PropertyState
ErrorBar::getPropertyState( const OUString
& rPropName
)
294 if(rPropName
== "ErrorBarStyle")
296 if(meStyle
== css::chart::ErrorBarStyle::NONE
)
297 return beans::PropertyState_DEFAULT_VALUE
;
298 return beans::PropertyState_DIRECT_VALUE
;
300 else if(rPropName
== "PositiveError")
302 if(mbShowPositiveError
)
306 case css::chart::ErrorBarStyle::ABSOLUTE
:
307 case css::chart::ErrorBarStyle::ERROR_MARGIN
:
308 return beans::PropertyState_DIRECT_VALUE
;
313 return beans::PropertyState_DEFAULT_VALUE
;
315 else if(rPropName
== "NegativeError")
317 if(mbShowNegativeError
)
321 case css::chart::ErrorBarStyle::ABSOLUTE
:
322 case css::chart::ErrorBarStyle::ERROR_MARGIN
:
323 return beans::PropertyState_DIRECT_VALUE
;
328 return beans::PropertyState_DEFAULT_VALUE
;
330 else if(rPropName
== "PercentageError")
332 if(meStyle
!= css::chart::ErrorBarStyle::RELATIVE
)
333 return beans::PropertyState_DEFAULT_VALUE
;
334 return beans::PropertyState_DIRECT_VALUE
;
336 else if(rPropName
== "ShowPositiveError")
338 // this value should be never default
339 return beans::PropertyState_DIRECT_VALUE
;
341 else if(rPropName
== "ShowNegativeError")
343 // this value should be never default
344 return beans::PropertyState_DIRECT_VALUE
;
346 else if(rPropName
== "ErrorBarRangePositive")
348 if(meStyle
== css::chart::ErrorBarStyle::FROM_DATA
&& mbShowPositiveError
)
349 return beans::PropertyState_DIRECT_VALUE
;
350 return beans::PropertyState_DEFAULT_VALUE
;
352 else if(rPropName
== "ErrorBarRangeNegative")
354 if(meStyle
== css::chart::ErrorBarStyle::FROM_DATA
&& mbShowNegativeError
)
355 return beans::PropertyState_DIRECT_VALUE
;
356 return beans::PropertyState_DEFAULT_VALUE
;
359 return beans::PropertyState_DIRECT_VALUE
;
362 uno::Sequence
< beans::PropertyState
> ErrorBar::getPropertyStates( const uno::Sequence
< OUString
>& rPropNames
)
364 uno::Sequence
< beans::PropertyState
> aRet( rPropNames
.getLength() );
365 auto aRetRange
= asNonConstRange(aRet
);
366 for(sal_Int32 i
= 0; i
< rPropNames
.getLength(); ++i
)
368 aRetRange
[i
] = getPropertyState(rPropNames
[i
]);
373 void ErrorBar::setPropertyToDefault( const OUString
& )
375 //keep them unimplemented for now
378 uno::Any
ErrorBar::getPropertyDefault( const OUString
& )
380 //keep them unimplemented for now
384 void ErrorBar::addPropertyChangeListener( const OUString
&, const css::uno::Reference
< css::beans::XPropertyChangeListener
>& )
388 void ErrorBar::removePropertyChangeListener( const OUString
&, const css::uno::Reference
< css::beans::XPropertyChangeListener
>& )
392 void ErrorBar::addVetoableChangeListener( const OUString
&, const css::uno::Reference
< css::beans::XVetoableChangeListener
>& )
396 void ErrorBar::removeVetoableChangeListener( const OUString
&, const css::uno::Reference
< css::beans::XVetoableChangeListener
>& )
400 // ____ XModifyBroadcaster ____
401 void SAL_CALL
ErrorBar::addModifyListener( const uno::Reference
< util::XModifyListener
>& aListener
)
403 m_xModifyEventForwarder
->addModifyListener( aListener
);
406 void SAL_CALL
ErrorBar::removeModifyListener( const uno::Reference
< util::XModifyListener
>& aListener
)
408 m_xModifyEventForwarder
->removeModifyListener( aListener
);
411 // ____ XModifyListener ____
412 void SAL_CALL
ErrorBar::modified( const lang::EventObject
& aEvent
)
414 m_xModifyEventForwarder
->modified( aEvent
);
417 // ____ XEventListener (base of XModifyListener) ____
418 void SAL_CALL
ErrorBar::disposing( const lang::EventObject
& /* Source */ )
423 // ____ XDataSink ____
424 void SAL_CALL
ErrorBar::setData( const uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> >& aData
)
426 ModifyListenerHelper::removeListenerFromAllElements( m_aDataSequences
, m_xModifyEventForwarder
);
427 EventListenerHelper::removeListenerFromAllElements( m_aDataSequences
, this );
428 m_aDataSequences
= comphelper::sequenceToContainer
<tDataSequenceContainer
>( aData
);
429 EventListenerHelper::addListenerToAllElements( m_aDataSequences
, this );
430 ModifyListenerHelper::addListenerToAllElements( m_aDataSequences
, m_xModifyEventForwarder
);
433 // ____ XDataSource ____
434 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > SAL_CALL
ErrorBar::getDataSequences()
436 return comphelper::containerToSequence( m_aDataSequences
);
439 OUString SAL_CALL
ErrorBar::getImplementationName()
441 return lcl_aServiceName
;
444 sal_Bool SAL_CALL
ErrorBar::supportsService( const OUString
& rServiceName
)
446 return cppu::supportsService(this, rServiceName
);
449 css::uno::Sequence
< OUString
> SAL_CALL
ErrorBar::getSupportedServiceNames()
453 "com.sun.star.chart2.ErrorBar"
457 // needed by MSC compiler
458 using impl::ErrorBar_Base
;
462 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
463 com_sun_star_comp_chart2_ErrorBar_get_implementation(css::uno::XComponentContext
*,
464 css::uno::Sequence
<css::uno::Any
> const &)
466 return cppu::acquire(new ::chart::ErrorBar
);
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */