tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / chart2 / source / model / main / DataSeries.cxx
blob247c3178c27e3850ad984a7936b82a2761665062
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 <DataSeries.hxx>
21 #include <DataSeriesProperties.hxx>
22 #include "DataPointProperties.hxx"
23 #include <CharacterProperties.hxx>
24 #include <UserDefinedProperties.hxx>
25 #include "DataPoint.hxx"
26 #include <DataSeriesHelper.hxx>
27 #include <CloneHelper.hxx>
28 #include <RegressionCurveModel.hxx>
29 #include <ModifyListenerHelper.hxx>
30 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
31 #include <com/sun/star/container/NoSuchElementException.hpp>
32 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <comphelper/diagnose_ex.hxx>
35 #include <rtl/ref.hxx>
36 #include <rtl/ustrbuf.hxx>
38 #include <algorithm>
40 namespace com::sun::star::uno { class XComponentContext; }
42 using namespace ::com::sun::star;
44 using ::com::sun::star::beans::Property;
45 using ::com::sun::star::uno::Sequence;
46 using ::com::sun::star::uno::Reference;
47 using ::osl::MutexGuard;
49 namespace chart
51 const ::chart::tPropertyValueMap & StaticDataSeriesDefaults()
53 static const ::chart::tPropertyValueMap aStaticDefaults = []()
55 ::chart::tPropertyValueMap aMap;
56 ::chart::DataSeriesProperties::AddDefaultsToMap( aMap );
57 ::chart::CharacterProperties::AddDefaultsToMap( aMap );
58 float fDefaultCharHeight = 10.0;
59 ::chart::PropertyHelper::setPropertyValue( aMap, ::chart::CharacterProperties::PROP_CHAR_CHAR_HEIGHT, fDefaultCharHeight );
60 ::chart::PropertyHelper::setPropertyValue( aMap, ::chart::CharacterProperties::PROP_CHAR_ASIAN_CHAR_HEIGHT, fDefaultCharHeight );
61 ::chart::PropertyHelper::setPropertyValue( aMap, ::chart::CharacterProperties::PROP_CHAR_COMPLEX_CHAR_HEIGHT, fDefaultCharHeight );
62 return aMap;
63 }();
64 return aStaticDefaults;
66 } // namespace chart
68 namespace
71 ::cppu::OPropertyArrayHelper& StaticDataSeriesInfoHelper()
73 static ::cppu::OPropertyArrayHelper oHelper = []()
75 std::vector< css::beans::Property > aProperties;
76 ::chart::DataSeriesProperties::AddPropertiesToVector( aProperties );
77 ::chart::CharacterProperties::AddPropertiesToVector( aProperties );
78 ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties );
80 std::sort( aProperties.begin(), aProperties.end(),
81 ::chart::PropertyNameLess() );
83 return comphelper::containerToSequence( aProperties );
84 }();
85 return oHelper;
88 void lcl_SetParent(
89 const uno::Reference< uno::XInterface > & xChildInterface,
90 const uno::Reference< uno::XInterface > & xParentInterface )
92 uno::Reference< container::XChild > xChild( xChildInterface, uno::UNO_QUERY );
93 if( xChild.is())
94 xChild->setParent( xParentInterface );
97 typedef std::map< sal_Int32, css::uno::Reference< css::beans::XPropertySet > >
98 lcl_tDataPointMap;
100 void lcl_CloneAttributedDataPoints(
101 const lcl_tDataPointMap & rSource, lcl_tDataPointMap & rDestination,
102 const uno::Reference< uno::XInterface > & xSeries )
104 for (auto const& elem : rSource)
106 Reference< beans::XPropertySet > xPoint( elem.second );
107 if( xPoint.is())
109 Reference< util::XCloneable > xCloneable( xPoint, uno::UNO_QUERY );
110 if( xCloneable.is())
112 xPoint.set( xCloneable->createClone(), uno::UNO_QUERY );
113 if( xPoint.is())
115 lcl_SetParent( xPoint, xSeries );
116 rDestination.emplace( elem.first, xPoint );
123 } // anonymous namespace
125 namespace chart
128 DataSeries::DataSeries() :
129 m_xModifyEventForwarder( new ModifyEventForwarder() )
133 DataSeries::DataSeries( const DataSeries & rOther ) :
134 impl::DataSeries_Base(rOther),
135 ::property::OPropertySet( rOther ),
136 m_xModifyEventForwarder( new ModifyEventForwarder() )
138 if( ! rOther.m_aDataSequences.empty())
140 CloneHelper::CloneRefVector(rOther.m_aDataSequences, m_aDataSequences );
141 ModifyListenerHelper::addListenerToAllElements( m_aDataSequences, m_xModifyEventForwarder );
144 CloneHelper::CloneRefVector( rOther.m_aRegressionCurves, m_aRegressionCurves );
145 ModifyListenerHelper::addListenerToAllElements( m_aRegressionCurves, m_xModifyEventForwarder );
147 // add as listener to XPropertySet properties
148 Reference< beans::XPropertySet > xPropertySet;
149 uno::Any aValue;
151 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X );
152 if( ( aValue >>= xPropertySet )
153 && xPropertySet.is())
154 ModifyListenerHelper::addListener( xPropertySet, m_xModifyEventForwarder );
156 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y );
157 if( ( aValue >>= xPropertySet )
158 && xPropertySet.is())
159 ModifyListenerHelper::addListener( xPropertySet, m_xModifyEventForwarder );
162 // late initialization to call after copy-constructing
163 void DataSeries::Init( const DataSeries & rOther )
165 Reference< uno::XInterface > xThisInterface( static_cast< ::cppu::OWeakObject * >( this ));
166 if( ! rOther.m_aAttributedDataPoints.empty())
168 lcl_CloneAttributedDataPoints(
169 rOther.m_aAttributedDataPoints, m_aAttributedDataPoints, xThisInterface );
170 ModifyListenerHelper::addListenerToAllMapElements( m_aAttributedDataPoints, m_xModifyEventForwarder );
173 // add as parent to error bars
174 Reference< beans::XPropertySet > xPropertySet;
175 uno::Any aValue;
177 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X );
178 if( ( aValue >>= xPropertySet )
179 && xPropertySet.is())
180 lcl_SetParent( xPropertySet, xThisInterface );
182 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y );
183 if( ( aValue >>= xPropertySet )
184 && xPropertySet.is())
185 lcl_SetParent( xPropertySet, xThisInterface );
188 DataSeries::~DataSeries()
192 ModifyListenerHelper::removeListenerFromAllMapElements( m_aAttributedDataPoints, m_xModifyEventForwarder );
193 ModifyListenerHelper::removeListenerFromAllElements( m_aRegressionCurves, m_xModifyEventForwarder );
194 ModifyListenerHelper::removeListenerFromAllElements( m_aDataSequences, m_xModifyEventForwarder );
196 // remove listener from XPropertySet properties
197 Reference< beans::XPropertySet > xPropertySet;
198 uno::Any aValue;
200 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X );
201 if( ( aValue >>= xPropertySet )
202 && xPropertySet.is())
203 ModifyListenerHelper::removeListener( xPropertySet, m_xModifyEventForwarder );
205 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y );
206 if( ( aValue >>= xPropertySet )
207 && xPropertySet.is())
208 ModifyListenerHelper::removeListener( xPropertySet, m_xModifyEventForwarder );
210 catch( const uno::Exception & )
212 DBG_UNHANDLED_EXCEPTION("chart2");
216 // ____ XCloneable ____
217 uno::Reference< util::XCloneable > SAL_CALL DataSeries::createClone()
219 rtl::Reference<DataSeries> pNewSeries( new DataSeries( *this ));
220 // do initialization that uses uno references to the clone
221 pNewSeries->Init( *this );
223 return pNewSeries;
226 // ____ OPropertySet ____
227 void DataSeries::GetDefaultValue( sal_Int32 nHandle, uno::Any& rDest ) const
229 const tPropertyValueMap& rStaticDefaults = StaticDataSeriesDefaults();
230 tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
231 if( aFound == rStaticDefaults.end() )
232 rDest.clear();
233 else
234 rDest = (*aFound).second;
237 // ____ OPropertySet ____
238 ::cppu::IPropertyArrayHelper & SAL_CALL DataSeries::getInfoHelper()
240 return StaticDataSeriesInfoHelper();
243 // ____ XPropertySet ____
244 uno::Reference< beans::XPropertySetInfo > SAL_CALL DataSeries::getPropertySetInfo()
246 static uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
247 ::cppu::OPropertySetHelper::createPropertySetInfo(StaticDataSeriesInfoHelper() );
248 return xPropSetInfo;
251 void SAL_CALL DataSeries::getFastPropertyValue
252 ( uno::Any& rValue,
253 sal_Int32 nHandle ) const
255 // special handling for get. set is not possible for this property
256 if( nHandle == DataSeriesProperties::PROP_DATASERIES_ATTRIBUTED_DATA_POINTS )
258 // TODO: only add those property sets that are really modified
260 rValue <<= comphelper::mapKeysToSequence(m_aAttributedDataPoints);
262 else
263 OPropertySet::getFastPropertyValue( rValue, nHandle );
266 void SAL_CALL DataSeries::setFastPropertyValue_NoBroadcast(
267 sal_Int32 nHandle, const uno::Any& rValue )
269 if( nHandle == DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y
270 || nHandle == DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X )
272 uno::Any aOldValue;
273 Reference< util::XModifyBroadcaster > xBroadcaster;
274 getFastPropertyValue( aOldValue, nHandle );
275 if( aOldValue.hasValue() &&
276 (aOldValue >>= xBroadcaster) &&
277 xBroadcaster.is())
279 ModifyListenerHelper::removeListener( xBroadcaster, m_xModifyEventForwarder );
282 OSL_ASSERT( rValue.getValueTypeClass() == uno::TypeClass_INTERFACE );
283 if( rValue.hasValue() &&
284 (rValue >>= xBroadcaster) &&
285 xBroadcaster.is())
287 ModifyListenerHelper::addListener( xBroadcaster, m_xModifyEventForwarder );
291 ::property::OPropertySet::setFastPropertyValue_NoBroadcast( nHandle, rValue );
294 Reference< beans::XPropertySet >
295 SAL_CALL DataSeries::getDataPointByIndex( sal_Int32 nIndex )
297 Reference< beans::XPropertySet > xResult;
299 std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences;
301 MutexGuard aGuard( m_aMutex );
302 aSequences = m_aDataSequences;
305 std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aValuesSeries(
306 DataSeriesHelper::getAllDataSequencesByRole( aSequences , u"values"_ustr ) );
308 if (aValuesSeries.empty())
309 throw lang::IndexOutOfBoundsException();
311 Reference< chart2::data::XDataSequence > xSeq( aValuesSeries.front()->getValues() );
312 if( 0 <= nIndex && nIndex < xSeq->getData().getLength() )
315 MutexGuard aGuard( m_aMutex );
316 tDataPointAttributeContainer::iterator aIt( m_aAttributedDataPoints.find( nIndex ) );
317 if( aIt != m_aAttributedDataPoints.end() )
318 xResult = (*aIt).second;
320 if( !xResult.is() )
322 Reference< beans::XPropertySet > xParentProperties;
323 Reference< util::XModifyListener > xModifyEventForwarder;
325 MutexGuard aGuard( m_aMutex );
326 xParentProperties = this;
327 xModifyEventForwarder = m_xModifyEventForwarder;
330 // create a new XPropertySet for this data point
331 xResult.set( new DataPoint( xParentProperties ) );
333 MutexGuard aGuard( m_aMutex );
334 m_aAttributedDataPoints[ nIndex ] = xResult;
336 ModifyListenerHelper::addListener( xResult, xModifyEventForwarder );
340 return xResult;
343 void SAL_CALL DataSeries::resetDataPoint( sal_Int32 nIndex )
345 Reference< beans::XPropertySet > xDataPointProp;
346 Reference< util::XModifyListener > xModifyEventForwarder;
348 MutexGuard aGuard( m_aMutex );
349 xModifyEventForwarder = m_xModifyEventForwarder;
350 tDataPointAttributeContainer::iterator aIt( m_aAttributedDataPoints.find( nIndex ));
351 if( aIt != m_aAttributedDataPoints.end())
353 xDataPointProp = (*aIt).second;
354 m_aAttributedDataPoints.erase(aIt);
358 if( xDataPointProp.is() )
360 Reference< util::XModifyBroadcaster > xBroadcaster( xDataPointProp, uno::UNO_QUERY );
361 if( xBroadcaster.is() && xModifyEventForwarder.is())
362 xBroadcaster->removeModifyListener( xModifyEventForwarder );
363 fireModifyEvent();
367 void SAL_CALL DataSeries::resetAllDataPoints()
369 tDataPointAttributeContainer aOldAttributedDataPoints;
370 Reference< util::XModifyListener > xModifyEventForwarder;
372 MutexGuard aGuard( m_aMutex );
373 xModifyEventForwarder = m_xModifyEventForwarder;
374 std::swap( aOldAttributedDataPoints, m_aAttributedDataPoints );
376 ModifyListenerHelper::removeListenerFromAllMapElements( aOldAttributedDataPoints, xModifyEventForwarder );
377 aOldAttributedDataPoints.clear();
378 fireModifyEvent();
381 // ____ XDataSink ____
382 void SAL_CALL DataSeries::setData( const uno::Sequence< Reference< chart2::data::XLabeledDataSequence > >& aData )
384 tDataSequenceContainer aOldDataSequences;
385 tDataSequenceContainer aNewDataSequences;
386 Reference< util::XModifyListener > xModifyEventForwarder;
388 MutexGuard aGuard( m_aMutex );
389 xModifyEventForwarder = m_xModifyEventForwarder;
390 std::swap( aOldDataSequences, m_aDataSequences );
391 for (const auto & i : aData)
393 aNewDataSequences.push_back(i);
395 m_aDataSequences = aNewDataSequences;
397 ModifyListenerHelper::removeListenerFromAllElements( aOldDataSequences, xModifyEventForwarder );
398 ModifyListenerHelper::addListenerToAllElements( aNewDataSequences, xModifyEventForwarder );
399 fireModifyEvent();
402 void DataSeries::setData( const std::vector< uno::Reference< chart2::data::XLabeledDataSequence > >& aData )
404 tDataSequenceContainer aOldDataSequences;
405 tDataSequenceContainer aNewDataSequences;
406 Reference< util::XModifyListener > xModifyEventForwarder;
408 MutexGuard aGuard( m_aMutex );
409 xModifyEventForwarder = m_xModifyEventForwarder;
410 std::swap( aOldDataSequences, m_aDataSequences );
411 aNewDataSequences = aData;
412 m_aDataSequences = aNewDataSequences;
414 ModifyListenerHelper::removeListenerFromAllElements( aOldDataSequences, xModifyEventForwarder );
415 ModifyListenerHelper::addListenerToAllElements( aNewDataSequences, xModifyEventForwarder );
416 fireModifyEvent();
419 void DataSeries::addDataSequence(css::uno::Reference<css::chart2::data::XLabeledDataSequence> const& rSequence)
421 m_aDataSequences.push_back(rSequence);
424 // ____ XDataSource ____
425 Sequence< Reference< chart2::data::XLabeledDataSequence > > SAL_CALL DataSeries::getDataSequences()
427 MutexGuard aGuard( m_aMutex );
428 return comphelper::containerToSequence<Reference< chart2::data::XLabeledDataSequence >>( m_aDataSequences );
431 // ____ XRegressionCurveContainer ____
432 void SAL_CALL DataSeries::addRegressionCurve(
433 const uno::Reference< chart2::XRegressionCurve >& xRegressionCurve )
435 auto pRegressionCurve = dynamic_cast<RegressionCurveModel*>(xRegressionCurve.get());
436 assert(pRegressionCurve);
437 Reference< util::XModifyListener > xModifyEventForwarder;
439 MutexGuard aGuard( m_aMutex );
440 xModifyEventForwarder = m_xModifyEventForwarder;
441 if( std::find( m_aRegressionCurves.begin(), m_aRegressionCurves.end(), pRegressionCurve )
442 != m_aRegressionCurves.end())
443 throw lang::IllegalArgumentException(u"curve not found"_ustr, static_cast<cppu::OWeakObject*>(this), 1);
444 m_aRegressionCurves.push_back( pRegressionCurve );
446 ModifyListenerHelper::addListener( rtl::Reference<RegressionCurveModel>(pRegressionCurve), xModifyEventForwarder );
447 fireModifyEvent();
450 void SAL_CALL DataSeries::removeRegressionCurve(
451 const uno::Reference< chart2::XRegressionCurve >& xRegressionCurve )
453 if( !xRegressionCurve.is() )
454 throw container::NoSuchElementException();
455 auto pRegressionCurve = dynamic_cast<RegressionCurveModel*>(xRegressionCurve.get());
456 assert(pRegressionCurve);
458 Reference< util::XModifyListener > xModifyEventForwarder;
460 MutexGuard aGuard( m_aMutex );
461 xModifyEventForwarder = m_xModifyEventForwarder;
462 tRegressionCurveContainerType::iterator aIt(
463 std::find( m_aRegressionCurves.begin(), m_aRegressionCurves.end(), pRegressionCurve ) );
464 if( aIt == m_aRegressionCurves.end())
465 throw container::NoSuchElementException(
466 u"The given regression curve is no element of this series"_ustr,
467 static_cast< uno::XWeak * >( this ));
468 m_aRegressionCurves.erase( aIt );
471 ModifyListenerHelper::removeListener( rtl::Reference<RegressionCurveModel>(pRegressionCurve), xModifyEventForwarder );
472 fireModifyEvent();
475 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > SAL_CALL DataSeries::getRegressionCurves()
477 MutexGuard aGuard( m_aMutex );
478 return comphelper::containerToSequence<uno::Reference< chart2::XRegressionCurve >>( m_aRegressionCurves );
481 void SAL_CALL DataSeries::setRegressionCurves(
482 const Sequence< Reference< chart2::XRegressionCurve > >& aRegressionCurves )
484 tRegressionCurveContainerType aOldCurves;
485 tRegressionCurveContainerType aNewCurves;
486 for (const auto & i : aRegressionCurves)
488 auto pRegressionCurve = dynamic_cast<RegressionCurveModel*>(i.get());
489 assert(pRegressionCurve);
490 aNewCurves.push_back(pRegressionCurve);
492 Reference< util::XModifyListener > xModifyEventForwarder;
494 MutexGuard aGuard( m_aMutex );
495 xModifyEventForwarder = m_xModifyEventForwarder;
496 std::swap( aOldCurves, m_aRegressionCurves );
497 m_aRegressionCurves = aNewCurves;
499 ModifyListenerHelper::removeListenerFromAllElements( aOldCurves, xModifyEventForwarder );
500 ModifyListenerHelper::addListenerToAllElements( aNewCurves, xModifyEventForwarder );
501 fireModifyEvent();
504 // ____ XModifyBroadcaster ____
505 void SAL_CALL DataSeries::addModifyListener( const Reference< util::XModifyListener >& aListener )
507 m_xModifyEventForwarder->addModifyListener( aListener );
510 void SAL_CALL DataSeries::removeModifyListener( const Reference< util::XModifyListener >& aListener )
512 m_xModifyEventForwarder->removeModifyListener( aListener );
515 // ____ XModifyListener ____
516 void SAL_CALL DataSeries::modified( const lang::EventObject& aEvent )
518 m_xModifyEventForwarder->modified( aEvent );
521 // ____ XEventListener (base of XModifyListener) ____
522 void SAL_CALL DataSeries::disposing( const lang::EventObject& )
526 // ____ OPropertySet ____
527 void DataSeries::firePropertyChangeEvent()
529 fireModifyEvent();
532 void DataSeries::fireModifyEvent()
534 m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
537 using impl::DataSeries_Base;
538 using ::property::OPropertySet;
540 IMPLEMENT_FORWARD_XINTERFACE2( DataSeries, DataSeries_Base, OPropertySet )
541 IMPLEMENT_FORWARD_XTYPEPROVIDER2( DataSeries, DataSeries_Base, OPropertySet )
543 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
544 OUString SAL_CALL DataSeries::getImplementationName()
546 return u"com.sun.star.comp.chart.DataSeries"_ustr;
549 sal_Bool SAL_CALL DataSeries::supportsService( const OUString& rServiceName )
551 return cppu::supportsService(this, rServiceName);
554 css::uno::Sequence< OUString > SAL_CALL DataSeries::getSupportedServiceNames()
556 return {
557 u"com.sun.star.chart2.DataSeries"_ustr,
558 u"com.sun.star.chart2.DataPointProperties"_ustr,
559 u"com.sun.star.beans.PropertySet"_ustr };
562 static Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel(
563 const Sequence< Reference< chart2::data::XLabeledDataSequence > > & rDataSequences )
565 Reference< chart2::data::XLabeledDataSequence > xResult;
567 for( auto const & labeledData : rDataSequences )
569 OSL_ENSURE( labeledData.is(), "empty LabeledDataSequence" );
570 // no values are set but a label exists
571 if( labeledData.is() &&
572 ( ! labeledData->getValues().is() &&
573 labeledData->getLabel().is()))
575 xResult.set( labeledData );
576 break;
580 return xResult;
583 static OUString lcl_getDataSequenceLabel( const Reference< chart2::data::XDataSequence > & xSequence )
585 OUString aResult;
587 Reference< chart2::data::XTextualDataSequence > xTextSeq( xSequence, uno::UNO_QUERY );
588 if( xTextSeq.is())
590 Sequence< OUString > aSeq( xTextSeq->getTextualData());
592 const sal_Int32 nMax = aSeq.getLength() - 1;
593 OUStringBuffer aBuf;
595 for( sal_Int32 i = 0; i <= nMax; ++i )
597 aBuf.append( aSeq[i] );
598 if( i < nMax )
599 aBuf.append( ' ');
601 aResult = aBuf.makeStringAndClear();
603 else if( xSequence.is())
605 Sequence< uno::Any > aSeq( xSequence->getData());
607 const sal_Int32 nMax = aSeq.getLength() - 1;
608 OUString aVal;
609 OUStringBuffer aBuf;
610 double fNum = 0;
612 for( sal_Int32 i = 0; i <= nMax; ++i )
614 if( aSeq[i] >>= aVal )
616 aBuf.append( aVal );
617 if( i < nMax )
618 aBuf.append( ' ');
620 else if( aSeq[ i ] >>= fNum )
622 aBuf.append( fNum );
623 if( i < nMax )
624 aBuf.append( ' ');
627 aResult = aBuf.makeStringAndClear();
630 return aResult;
633 static OUString getLabelForLabeledDataSequence(
634 const Reference< chart2::data::XLabeledDataSequence > & xLabeledSeq )
636 OUString aResult;
637 if( xLabeledSeq.is())
639 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
640 if( xSeq.is() )
641 aResult = lcl_getDataSequenceLabel( xSeq );
642 if( !xSeq.is() || aResult.isEmpty() )
644 // no label set or label content is empty -> use auto-generated one
645 Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
646 if( xValueSeq.is() )
648 Sequence< OUString > aLabels( xValueSeq->generateLabel(
649 chart2::data::LabelOrigin_SHORT_SIDE ) );
650 // no labels returned is interpreted as: auto-generation not
651 // supported by sequence
652 if( aLabels.hasElements() )
653 aResult=aLabels[0];
654 else
656 //todo?: maybe use the index of the series as name
657 //but as the index may change it would be better to have such a name persistent
658 //what is not possible at the moment
659 //--> maybe use the identifier as part of the name ...
660 aResult = lcl_getDataSequenceLabel( xValueSeq );
665 return aResult;
668 OUString DataSeries::getLabelForRole( const OUString & rLabelSequenceRole )
670 OUString aResult;
672 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
673 ::chart::DataSeriesHelper::getDataSequenceByRole( this, rLabelSequenceRole ));
674 if( xLabeledSeq.is())
675 aResult = getLabelForLabeledDataSequence( xLabeledSeq );
676 else
678 // special case: labeled data series with only a label and no values may
679 // serve as label
680 xLabeledSeq.set( lcl_findLSequenceWithOnlyLabel( getDataSequences() ));
681 if( xLabeledSeq.is())
683 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
684 if( xSeq.is())
685 aResult = lcl_getDataSequenceLabel( xSeq );
689 return aResult;
692 static bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
694 if (!xDataSequence.is())
695 return false;
696 uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
697 if( xProp.is() )
699 uno::Sequence< sal_Int32 > aHiddenValues;
702 xProp->getPropertyValue( u"HiddenValues"_ustr ) >>= aHiddenValues;
703 if( !aHiddenValues.hasElements() )
704 return true;
706 catch( const uno::Exception& )
708 return true;
711 return xDataSequence->getData().hasElements();
714 bool DataSeries::hasUnhiddenData()
716 MutexGuard aGuard( m_aMutex );
718 for(uno::Reference< chart2::data::XLabeledDataSequence > const & rDataSequence : m_aDataSequences)
720 if( !rDataSequence.is() )
721 continue;
722 if( lcl_SequenceHasUnhiddenData( rDataSequence->getValues() ) )
723 return true;
725 return false;
729 } // namespace chart
731 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
732 com_sun_star_comp_chart_DataSeries_get_implementation(css::uno::XComponentContext *,
733 css::uno::Sequence<css::uno::Any> const &)
735 return cppu::acquire(new ::chart::DataSeries );
738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */