diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /chart2/source/model/template | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'chart2/source/model/template')
53 files changed, 10503 insertions, 0 deletions
diff --git a/chart2/source/model/template/AreaChartType.cxx b/chart2/source/model/template/AreaChartType.cxx new file mode 100644 index 000000000..840bdba03 --- /dev/null +++ b/chart2/source/model/template/AreaChartType.cxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "AreaChartType.hxx" +#include <servicenames_charttypes.hxx> +#include <cppuhelper/supportsservice.hxx> + +namespace com::sun::star::uno { class XComponentContext; } + +using namespace ::com::sun::star; + +namespace chart +{ + +AreaChartType::AreaChartType() +{} + +AreaChartType::AreaChartType( const AreaChartType & rOther ) : + ChartType( rOther ) +{} + +AreaChartType::~AreaChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL AreaChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new AreaChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL AreaChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_AREA; +} + +OUString SAL_CALL AreaChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.AreaChartType"; +} + +sal_Bool SAL_CALL AreaChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL AreaChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_AREA, + "com.sun.star.chart2.ChartType" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_AreaChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::AreaChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/AreaChartType.hxx b/chart2/source/model/template/AreaChartType.hxx new file mode 100644 index 000000000..acb76ef10 --- /dev/null +++ b/chart2/source/model/template/AreaChartType.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_AREACHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_AREACHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class AreaChartType final : public ChartType +{ +public: + explicit AreaChartType(); + virtual ~AreaChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit AreaChartType( const AreaChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_AREACHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/AreaChartTypeTemplate.cxx b/chart2/source/model/template/AreaChartTypeTemplate.cxx new file mode 100644 index 000000000..401dc6971 --- /dev/null +++ b/chart2/source/model/template/AreaChartTypeTemplate.cxx @@ -0,0 +1,237 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "AreaChartTypeTemplate.hxx" +#include <servicenames_charttypes.hxx> +#include <DiagramHelper.hxx> +#include <DataSeriesHelper.hxx> +#include <PropertyHelper.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +#include <algorithm> + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace +{ + +enum +{ + PROP_AREA_TEMPLATE_DIMENSION +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "Dimension", + PROP_AREA_TEMPLATE_DIMENSION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticAreaChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aStaticDefaults, PROP_AREA_TEMPLATE_DIMENSION, 2 ); + return &aStaticDefaults; + } +}; + +struct StaticAreaChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticAreaChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticAreaChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static uno::Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticAreaChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticAreaChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticAreaChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticAreaChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticAreaChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticAreaChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +AreaChartTypeTemplate::AreaChartTypeTemplate( + uno::Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + sal_Int32 nDim /* = 2 */ ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ), + m_eStackMode( eStackMode ) +{ + setFastPropertyValue_NoBroadcast( PROP_AREA_TEMPLATE_DIMENSION, uno::Any( nDim )); +} + +AreaChartTypeTemplate::~AreaChartTypeTemplate() +{} + +// ____ OPropertySet ____ +uno::Any AreaChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticAreaChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL AreaChartTypeTemplate::getInfoHelper() +{ + return *StaticAreaChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL AreaChartTypeTemplate::getPropertySetInfo() +{ + return *StaticAreaChartTypeTemplateInfo::get(); +} + +sal_Int32 AreaChartTypeTemplate::getDimension() const +{ + sal_Int32 nDim = 2; + try + { + // note: UNO-methods are never const + const_cast< AreaChartTypeTemplate * >( this )-> + getFastPropertyValue( PROP_AREA_TEMPLATE_DIMENSION ) >>= nDim; + } + catch( const beans::UnknownPropertyException & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return nDim; +} + +StackMode AreaChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + return m_eStackMode; +} + +// ____ XChartTypeTemplate ____ +void SAL_CALL AreaChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); +} + +void SAL_CALL AreaChartTypeTemplate::resetStyles( const Reference< chart2::XDiagram >& xDiagram ) +{ + ChartTypeTemplate::resetStyles( xDiagram ); + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + uno::Any aLineStyleAny( drawing::LineStyle_NONE ); + for (auto const& series : aSeriesVec) + { + Reference< beans::XPropertyState > xState(series, uno::UNO_QUERY); + Reference< beans::XPropertySet > xProp(series, uno::UNO_QUERY); + if( xState.is() && + xProp.is() && + xProp->getPropertyValue( "BorderStyle") == aLineStyleAny ) + { + xState->setPropertyToDefault( "BorderStyle"); + } + } +} + +Reference< chart2::XChartType > AreaChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_AREA ), uno::UNO_QUERY_THROW ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XChartType > SAL_CALL AreaChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult( getChartTypeForIndex( 0 ) ); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + return xResult; +} + +IMPLEMENT_FORWARD_XINTERFACE2( AreaChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( AreaChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/AreaChartTypeTemplate.hxx b/chart2/source/model/template/AreaChartTypeTemplate.hxx new file mode 100644 index 000000000..e56be9833 --- /dev/null +++ b/chart2/source/model/template/AreaChartTypeTemplate.hxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_AREACHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_AREACHARTTYPETEMPLATE_HXX + +#include "ChartTypeTemplate.hxx" +#include <StackMode.hxx> + +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class AreaChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + explicit AreaChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + sal_Int32 nDim = 2 ); + virtual ~AreaChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< + css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void SAL_CALL resetStyles( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) override; + + // ____ ChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + virtual sal_Int32 getDimension() const override; + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; + +private: + StackMode m_eStackMode; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_AREACHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BarChartType.cxx b/chart2/source/model/template/BarChartType.cxx new file mode 100644 index 000000000..87675e3f1 --- /dev/null +++ b/chart2/source/model/template/BarChartType.cxx @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "BarChartType.hxx" +#include <servicenames_charttypes.hxx> +#include <cppuhelper/supportsservice.hxx> + +namespace com::sun::star::uno { class XComponentContext; } + +using namespace ::com::sun::star; + +namespace chart +{ + +BarChartType::BarChartType() +{} + +BarChartType::BarChartType( const BarChartType & rOther ) : + ChartType( rOther ) +{ +} + +BarChartType::~BarChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL BarChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new BarChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL BarChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_BAR; +} + +uno::Sequence< OUString > BarChartType::getSupportedPropertyRoles() +{ + uno::Sequence< OUString > aPropRoles(2); + aPropRoles[0] = "FillColor"; + aPropRoles[1] = "BorderColor"; + + return aPropRoles; +} + +OUString SAL_CALL BarChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.BarChartType"; +} + +sal_Bool SAL_CALL BarChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL BarChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_BAR, + "com.sun.star.chart2.ChartType" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_BarChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::BarChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BarChartType.hxx b/chart2/source/model/template/BarChartType.hxx new file mode 100644 index 000000000..4d090c783 --- /dev/null +++ b/chart2/source/model/template/BarChartType.hxx @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BARCHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BARCHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class BarChartType final : public ChartType +{ +public: + explicit BarChartType(); + virtual ~BarChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit BarChartType( const BarChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedPropertyRoles() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BARCHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BarChartTypeTemplate.cxx b/chart2/source/model/template/BarChartTypeTemplate.cxx new file mode 100644 index 000000000..dce1ffbb0 --- /dev/null +++ b/chart2/source/model/template/BarChartTypeTemplate.cxx @@ -0,0 +1,311 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "BarChartTypeTemplate.hxx" +#include <DiagramHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <DataSeriesHelper.hxx> +#include <PropertyHelper.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/chart2/DataPointGeometry3D.hpp> +#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +#include <algorithm> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::Property; + +namespace +{ + +enum +{ + PROP_BAR_TEMPLATE_DIMENSION, + PROP_BAR_TEMPLATE_GEOMETRY3D +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "Dimension", + PROP_BAR_TEMPLATE_DIMENSION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "Geometry3D", + PROP_BAR_TEMPLATE_GEOMETRY3D, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticBarChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_BAR_TEMPLATE_DIMENSION, 2 ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_BAR_TEMPLATE_GEOMETRY3D, ::chart2::DataPointGeometry3D::CUBOID ); + } +}; + +struct StaticBarChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticBarChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticBarChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticBarChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticBarChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticBarChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticBarChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticBarChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticBarChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +BarChartTypeTemplate::BarChartTypeTemplate( + Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + BarDirection eDirection, + sal_Int32 nDim /* = 2 */ ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ), + m_eStackMode( eStackMode ), + m_eBarDirection( eDirection ), + m_nDim( nDim ) +{} + +BarChartTypeTemplate::~BarChartTypeTemplate() +{} + +sal_Int32 BarChartTypeTemplate::getDimension() const +{ + return m_nDim; +} + +StackMode BarChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + return m_eStackMode; +} + +bool BarChartTypeTemplate::isSwapXAndY() const +{ + return (m_eBarDirection == HORIZONTAL); +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL BarChartTypeTemplate::matchesTemplate( + const Reference< chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties ); + + //check BarDirection + if( bResult ) + { + bool bFound = false; + bool bAmbiguous = false; + bool bVertical = DiagramHelper::getVertical( xDiagram, bFound, bAmbiguous ); + if( m_eBarDirection == HORIZONTAL ) + bResult = bVertical; + else if( m_eBarDirection == VERTICAL ) + bResult = !bVertical; + } + + // adapt solid-type of template according to values in series + if( bAdaptProperties && + bResult && + getDimension() == 3 ) + { + + bool bGeomFound = false, bGeomAmbiguous = false; + sal_Int32 aCommonGeom = DiagramHelper::getGeometry3D( xDiagram, bGeomFound, bGeomAmbiguous ); + + if( !bGeomAmbiguous ) + { + setFastPropertyValue_NoBroadcast( + PROP_BAR_TEMPLATE_GEOMETRY3D, uno::Any( aCommonGeom )); + } + } + + return bResult; +} +Reference< chart2::XChartType > BarChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ), uno::UNO_QUERY_THROW ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XChartType > SAL_CALL BarChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult( getChartTypeForIndex( 0 ) ); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + return xResult; +} + +// ____ OPropertySet ____ +uno::Any BarChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticBarChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL BarChartTypeTemplate::getInfoHelper() +{ + return *StaticBarChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +Reference< beans::XPropertySetInfo > SAL_CALL BarChartTypeTemplate::getPropertySetInfo() +{ + return *StaticBarChartTypeTemplateInfo::get(); +} + +void SAL_CALL BarChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); + if( getDimension() != 3 ) + return; + + try + { + //apply Geometry3D + uno::Any aAGeometry3D; + getFastPropertyValue( aAGeometry3D, PROP_BAR_TEMPLATE_GEOMETRY3D ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "Geometry3D", aAGeometry3D ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void SAL_CALL BarChartTypeTemplate::resetStyles( + const Reference< chart2::XDiagram >& xDiagram ) +{ + ChartTypeTemplate::resetStyles( xDiagram ); + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + uno::Any aLineStyleAny( drawing::LineStyle_NONE ); + for (auto const& series : aSeriesVec) + { + Reference< beans::XPropertyState > xState(series, uno::UNO_QUERY); + if( xState.is()) + { + if( getDimension() == 3 ) + xState->setPropertyToDefault( "Geometry3D"); + Reference< beans::XPropertySet > xProp( xState, uno::UNO_QUERY ); + if( xProp.is() && + xProp->getPropertyValue( "BorderStyle") == aLineStyleAny ) + { + xState->setPropertyToDefault( "BorderStyle"); + } + } + } + + DiagramHelper::setVertical( xDiagram, false ); +} + +void BarChartTypeTemplate::createCoordinateSystems( + const Reference< chart2::XCoordinateSystemContainer > & xCooSysCnt ) +{ + ChartTypeTemplate::createCoordinateSystems( xCooSysCnt ); + + Reference< chart2::XDiagram > xDiagram( xCooSysCnt, uno::UNO_QUERY ); + DiagramHelper::setVertical( xDiagram, m_eBarDirection == HORIZONTAL ); +} + +IMPLEMENT_FORWARD_XINTERFACE2( BarChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( BarChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BarChartTypeTemplate.hxx b/chart2/source/model/template/BarChartTypeTemplate.hxx new file mode 100644 index 000000000..593a1f7fe --- /dev/null +++ b/chart2/source/model/template/BarChartTypeTemplate.hxx @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BARCHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BARCHARTTYPETEMPLATE_HXX + +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <comphelper/uno3.hxx> + +#include "ChartTypeTemplate.hxx" +#include <StackMode.hxx> + +namespace chart +{ + +class BarChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + enum BarDirection + { + HORIZONTAL, + VERTICAL + }; + + explicit BarChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + BarDirection eDirection, + sal_Int32 nDim = 2 ); + virtual ~BarChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< + css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void SAL_CALL resetStyles( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) override; + + // ____ ChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + virtual sal_Int32 getDimension() const override; + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; + virtual bool isSwapXAndY() const override; + + virtual void createCoordinateSystems( + const css::uno::Reference< css::chart2::XCoordinateSystemContainer > & xCooSysCnt ) override; + +private: + StackMode m_eStackMode; + BarDirection m_eBarDirection; + sal_Int32 m_nDim; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BARCHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BubbleChartType.cxx b/chart2/source/model/template/BubbleChartType.cxx new file mode 100644 index 000000000..4abdbb826 --- /dev/null +++ b/chart2/source/model/template/BubbleChartType.cxx @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "BubbleChartType.hxx" +#include <PropertyHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <CartesianCoordinateSystem.hxx> +#include <AxisHelper.hxx> +#include <AxisIndexDefines.hxx> +#include <com/sun/star/chart2/AxisType.hpp> +#include <cppuhelper/supportsservice.hxx> + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace +{ + +struct StaticBubbleChartTypeDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + return &aStaticDefaults; + } +}; + +struct StaticBubbleChartTypeDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticBubbleChartTypeDefaults_Initializer > +{ +}; + +struct StaticBubbleChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } +}; + +struct StaticBubbleChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticBubbleChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticBubbleChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticBubbleChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticBubbleChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticBubbleChartTypeInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +BubbleChartType::BubbleChartType() +{ +} + +BubbleChartType::BubbleChartType( const BubbleChartType & rOther ) : + ChartType( rOther ) +{ +} + +BubbleChartType::~BubbleChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL BubbleChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new BubbleChartType( *this )); +} + +// ____ XChartType ____ +Reference< chart2::XCoordinateSystem > SAL_CALL + BubbleChartType::createCoordinateSystem( ::sal_Int32 DimensionCount ) +{ + Reference< chart2::XCoordinateSystem > xResult( + new CartesianCoordinateSystem( DimensionCount )); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + Reference< chart2::XAxis > xAxis( xResult->getAxisByDimension( i, MAIN_AXIS_INDEX ) ); + if( !xAxis.is() ) + { + OSL_FAIL("a created coordinate system should have an axis for each dimension"); + continue; + } + + chart2::ScaleData aScaleData = xAxis->getScaleData(); + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + aScaleData.Scaling = AxisHelper::createLinearScaling(); + + if( i == 2 ) + aScaleData.AxisType = chart2::AxisType::SERIES; + else + aScaleData.AxisType = chart2::AxisType::REALNUMBER; + + xAxis->setScaleData( aScaleData ); + } + + return xResult; +} + +OUString SAL_CALL BubbleChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE; +} + +uno::Sequence< OUString > SAL_CALL BubbleChartType::getSupportedMandatoryRoles() +{ + uno::Sequence< OUString > aMandRolesSeq(4); + aMandRolesSeq[0] = "label"; + aMandRolesSeq[1] = "values-x"; + aMandRolesSeq[2] = "values-y"; + aMandRolesSeq[3] = "values-size"; + return aMandRolesSeq; +} + +uno::Sequence< OUString > SAL_CALL BubbleChartType::getSupportedPropertyRoles() +{ + uno::Sequence< OUString > aPropertyRoles(2); + aPropertyRoles[0] = "FillColor"; + aPropertyRoles[1] = "BorderColor"; + return aPropertyRoles; +} + +OUString SAL_CALL BubbleChartType::getRoleOfSequenceForSeriesLabel() +{ + return "values-size"; +} + +// ____ OPropertySet ____ +uno::Any BubbleChartType::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticBubbleChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL BubbleChartType::getInfoHelper() +{ + return *StaticBubbleChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL BubbleChartType::getPropertySetInfo() +{ + return *StaticBubbleChartTypeInfo::get(); +} + +OUString SAL_CALL BubbleChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.BubbleChartType"; +} + +sal_Bool SAL_CALL BubbleChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL BubbleChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE, + "com.sun.star.chart2.ChartType", + "com.sun.star.beans.PropertySet" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_BubbleChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::BubbleChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BubbleChartType.hxx b/chart2/source/model/template/BubbleChartType.hxx new file mode 100644 index 000000000..e37a01ac2 --- /dev/null +++ b/chart2/source/model/template/BubbleChartType.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLECHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLECHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class BubbleChartType final : public ChartType +{ +public: + explicit BubbleChartType(); + virtual ~BubbleChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit BubbleChartType( const BubbleChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedMandatoryRoles() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedPropertyRoles() override; + virtual css::uno::Reference< css::chart2::XCoordinateSystem > SAL_CALL + createCoordinateSystem( ::sal_Int32 DimensionCount ) override; + virtual OUString SAL_CALL getRoleOfSequenceForSeriesLabel() override; + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + + // ____ OPropertySet ____ + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLECHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BubbleChartTypeTemplate.cxx b/chart2/source/model/template/BubbleChartTypeTemplate.cxx new file mode 100644 index 000000000..90ec1a75d --- /dev/null +++ b/chart2/source/model/template/BubbleChartTypeTemplate.cxx @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "BubbleChartTypeTemplate.hxx" +#include "BubbleDataInterpreter.hxx" +#include <servicenames_charttypes.hxx> +#include <DataSeriesHelper.hxx> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <PropertyHelper.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +#include <algorithm> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::Property; + +namespace +{ + +struct StaticBubbleChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + return &aStaticDefaults; + } +}; + +struct StaticBubbleChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticBubbleChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticBubbleChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticBubbleChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticBubbleChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticBubbleChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticBubbleChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticBubbleChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticBubbleChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +BubbleChartTypeTemplate::BubbleChartTypeTemplate( + Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ) +{ +} + +BubbleChartTypeTemplate::~BubbleChartTypeTemplate() +{} + +// ____ OPropertySet ____ +uno::Any BubbleChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticBubbleChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL BubbleChartTypeTemplate::getInfoHelper() +{ + return *StaticBubbleChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL BubbleChartTypeTemplate::getPropertySetInfo() +{ + return *StaticBubbleChartTypeTemplateInfo::get(); +} + +sal_Int32 BubbleChartTypeTemplate::getDimension() const +{ + return 2; +} + +StackMode BubbleChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + return StackMode::NONE; +} + +void SAL_CALL BubbleChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL BubbleChartTypeTemplate::supportsCategories() +{ + return false; +} + +Reference< chart2::XChartType > BubbleChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ), uno::UNO_QUERY_THROW ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XChartType > SAL_CALL BubbleChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE ), uno::UNO_QUERY_THROW ); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XDataInterpreter > SAL_CALL BubbleChartTypeTemplate::getDataInterpreter() +{ + if( ! m_xDataInterpreter.is()) + m_xDataInterpreter.set( new BubbleDataInterpreter ); + + return m_xDataInterpreter; +} + +IMPLEMENT_FORWARD_XINTERFACE2( BubbleChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( BubbleChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BubbleChartTypeTemplate.hxx b/chart2/source/model/template/BubbleChartTypeTemplate.hxx new file mode 100644 index 000000000..b771d6f57 --- /dev/null +++ b/chart2/source/model/template/BubbleChartTypeTemplate.hxx @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLECHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLECHARTTYPETEMPLATE_HXX + +#include "ChartTypeTemplate.hxx" +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class BubbleChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + explicit BubbleChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName ); + virtual ~BubbleChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL supportsCategories() override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual css::uno::Reference< css::chart2::XDataInterpreter > SAL_CALL getDataInterpreter() override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + + // ____ ChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + virtual sal_Int32 getDimension() const override; + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLECHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BubbleDataInterpreter.cxx b/chart2/source/model/template/BubbleDataInterpreter.cxx new file mode 100644 index 000000000..3078d3590 --- /dev/null +++ b/chart2/source/model/template/BubbleDataInterpreter.cxx @@ -0,0 +1,290 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "BubbleDataInterpreter.hxx" +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <CommonConverters.hxx> +#include <com/sun/star/chart2/data/XDataSink.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using namespace ::std; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +namespace chart +{ + +BubbleDataInterpreter::BubbleDataInterpreter() : + DataInterpreter() +{ +} + +BubbleDataInterpreter::~BubbleDataInterpreter() +{ +} + +// ____ XDataInterpreter ____ +chart2::InterpretedData SAL_CALL BubbleDataInterpreter::interpretDataSource( + const Reference< chart2::data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const Sequence< Reference< XDataSeries > >& aSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + + Sequence< Reference< data::XLabeledDataSequence > > aData( xSource->getDataSequences() ); + + Reference< data::XLabeledDataSequence > xValuesX; + vector< Reference< data::XLabeledDataSequence > > aYValuesVector; + vector< Reference< data::XLabeledDataSequence > > aSizeValuesVector; + + Reference< data::XLabeledDataSequence > xCategories; + bool bHasCategories = HasCategories( aArguments, aData ); + bool bUseCategoriesAsX = UseCategoriesAsX( aArguments ); + + sal_Int32 nDataSeqCount = aData.getLength(); + + bool bSetXValues = bHasCategories ? ( (nDataSeqCount-1) > 2 && (nDataSeqCount-1) % 2 != 0 ) + :( nDataSeqCount > 2 && nDataSeqCount % 2 != 0 ); + + bool bCategoriesUsed = false; + bool bNextIsYValues = bHasCategories ? nDataSeqCount>2 : nDataSeqCount>1; + for( sal_Int32 nDataIdx = 0; nDataIdx < nDataSeqCount; ++nDataIdx ) + { + try + { + if( bHasCategories && !bCategoriesUsed ) + { + xCategories.set( aData[nDataIdx] ); + if( xCategories.is()) + { + SetRole( xCategories->getValues(), "categories"); + if( bUseCategoriesAsX ) + { + bSetXValues = false; + bNextIsYValues = nDataSeqCount > 2; + } + } + bCategoriesUsed = true; + } + else if( !xValuesX.is() && bSetXValues ) + { + xValuesX.set( aData[nDataIdx] ); + if( xValuesX.is()) + SetRole( xValuesX->getValues(), "values-x"); + } + else if( bNextIsYValues ) + { + aYValuesVector.push_back( aData[nDataIdx] ); + if( aData[nDataIdx].is()) + SetRole( aData[nDataIdx]->getValues(), "values-y"); + bNextIsYValues = false; + } + else if( !bNextIsYValues ) + { + aSizeValuesVector.push_back( aData[nDataIdx] ); + if( aData[nDataIdx].is()) + SetRole( aData[nDataIdx]->getValues(), "values-size"); + bNextIsYValues = (nDataSeqCount-(nDataIdx+1)) >= 2;//two or more left + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + // create DataSeries + sal_Int32 nSeriesIndex = 0; + vector< Reference< XDataSeries > > aSeriesVec; + aSeriesVec.reserve( aSizeValuesVector.size()); + + Reference< data::XLabeledDataSequence > xClonedXValues = xValuesX; + Reference< util::XCloneable > xCloneableX( xValuesX, uno::UNO_QUERY ); + + for( size_t nN = 0; nN < aSizeValuesVector.size(); ++nN, ++nSeriesIndex ) + { + vector< Reference< data::XLabeledDataSequence > > aNewData; + if( xValuesX.is() ) + { + if( nN > 0 && xCloneableX.is() ) + xClonedXValues.set( xCloneableX->createClone(), uno::UNO_QUERY ); + aNewData.push_back( xClonedXValues ); + } + if( aYValuesVector.size() > nN ) + aNewData.push_back( aYValuesVector[nN] ); + aNewData.push_back(aSizeValuesVector[nN]); + + Reference< XDataSeries > xSeries; + if( nSeriesIndex < aSeriesToReUse.getLength()) + xSeries.set( aSeriesToReUse[nSeriesIndex] ); + else + xSeries.set( new DataSeries ); + OSL_ASSERT( xSeries.is() ); + Reference< data::XDataSink > xSink( xSeries, uno::UNO_QUERY ); + OSL_ASSERT( xSink.is() ); + xSink->setData( comphelper::containerToSequence( aNewData ) ); + + aSeriesVec.push_back( xSeries ); + } + + Sequence< Sequence< Reference< XDataSeries > > > aSeries(1); + aSeries[0] = comphelper::containerToSequence( aSeriesVec ); + return InterpretedData( aSeries, xCategories ); +} + +chart2::InterpretedData SAL_CALL BubbleDataInterpreter::reinterpretDataSeries( + const chart2::InterpretedData& aInterpretedData ) +{ + InterpretedData aResult( aInterpretedData ); + + sal_Int32 i=0; + Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + const sal_Int32 nCount = aSeries.getLength(); + for( ; i<nCount; ++i ) + { + try + { + Reference< data::XDataSource > xSeriesSource( aSeries[i], uno::UNO_QUERY_THROW ); + Sequence< Reference< data::XLabeledDataSequence > > aNewSequences; + + Reference< data::XLabeledDataSequence > xValuesSize( + DataSeriesHelper::getDataSequenceByRole( xSeriesSource, "values-size" )); + Reference< data::XLabeledDataSequence > xValuesY( + DataSeriesHelper::getDataSequenceByRole( xSeriesSource, "values-y" )); + Reference< data::XLabeledDataSequence > xValuesX( + DataSeriesHelper::getDataSequenceByRole( xSeriesSource, "values-x" )); + + if( ! xValuesX.is() || + ! xValuesY.is() || + ! xValuesSize.is() ) + { + vector< Reference< data::XLabeledDataSequence > > aValueSeqVec( + DataSeriesHelper::getAllDataSequencesByRole( + xSeriesSource->getDataSequences(), "values" )); + if( xValuesX.is()) + aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesX )); + if( xValuesY.is()) + aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesY )); + if( xValuesSize.is()) + aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesSize )); + + size_t nIndex = 0; + + if( ! xValuesSize.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesSize.set( aValueSeqVec[nIndex++] ); + if( xValuesSize.is()) + SetRole( xValuesSize->getValues(), "values-size"); + } + + if( ! xValuesY.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesY.set( aValueSeqVec[nIndex++] ); + if( xValuesY.is()) + SetRole( xValuesY->getValues(), "values-y"); + } + + if( ! xValuesX.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesX.set( aValueSeqVec[nIndex++] ); + if( xValuesX.is()) + SetRole( xValuesY->getValues(), "values-x"); + } + } + if( xValuesSize.is()) + { + if( xValuesY.is() ) + { + if( xValuesX.is() ) + { + aNewSequences.realloc(3); + aNewSequences[0] = xValuesX; + aNewSequences[1] = xValuesY; + aNewSequences[2] = xValuesSize; + } + else + { + aNewSequences.realloc(2); + aNewSequences[0] = xValuesY; + aNewSequences[1] = xValuesSize; + } + } + else + { + aNewSequences.realloc(1); + aNewSequences[0] = xValuesSize; + } + } + + const Sequence< Reference< data::XLabeledDataSequence > > aSeqs( xSeriesSource->getDataSequences()); + if( aSeqs.getLength() != aNewSequences.getLength() ) + { +#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG + for( auto const & j : aSeqs ) + { + assert( (j == xValuesY || j == xValuesX || j == xValuesSize) && "All sequences should be used" ); + } +#endif + Reference< data::XDataSink > xSink( xSeriesSource, uno::UNO_QUERY_THROW ); + xSink->setData( aNewSequences ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return aResult; +} + +sal_Bool SAL_CALL BubbleDataInterpreter::isDataCompatible( + const chart2::InterpretedData& aInterpretedData ) +{ + const Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + for( Reference< XDataSeries > const & dataSeries : aSeries ) + { + try + { + Reference< data::XDataSource > xSrc( dataSeries, uno::UNO_QUERY_THROW ); + Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSrc->getDataSequences()); + if( aSeq.getLength() != 3 ) + return false; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return true; +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/BubbleDataInterpreter.hxx b/chart2/source/model/template/BubbleDataInterpreter.hxx new file mode 100644 index 000000000..43921262e --- /dev/null +++ b/chart2/source/model/template/BubbleDataInterpreter.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLEDATAINTERPRETER_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLEDATAINTERPRETER_HXX + +#include "DataInterpreter.hxx" + +namespace chart +{ + +class BubbleDataInterpreter : public DataInterpreter +{ +public: + explicit BubbleDataInterpreter(); + virtual ~BubbleDataInterpreter() override; + +protected: + // ____ XDataInterpreter ____ + virtual css::chart2::InterpretedData SAL_CALL interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const css::uno::Sequence< css::uno::Reference< css::chart2::XDataSeries > >& aSeriesToReUse ) override; + virtual css::chart2::InterpretedData SAL_CALL reinterpretDataSeries( + const css::chart2::InterpretedData& aInterpretedData ) override; + virtual sal_Bool SAL_CALL isDataCompatible( + const css::chart2::InterpretedData& aInterpretedData ) override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_BUBBLEDATAINTERPRETER_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/CandleStickChartType.cxx b/chart2/source/model/template/CandleStickChartType.cxx new file mode 100644 index 000000000..af0c1f04f --- /dev/null +++ b/chart2/source/model/template/CandleStickChartType.cxx @@ -0,0 +1,342 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "CandleStickChartType.hxx" +#include <PropertyHelper.hxx> +#include <StockBar.hxx> +#include <ModifyListenerHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <tools/diagnose_ex.h> + +namespace com::sun::star::uno { class XComponentContext; } + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace +{ + +enum +{ + PROP_CANDLESTICKCHARTTYPE_JAPANESE, + PROP_CANDLESTICKCHARTTYPE_WHITE_DAY, + PROP_CANDLESTICKCHARTTYPE_BLACK_DAY, + + PROP_CANDLESTICKCHARTTYPE_SHOW_FIRST, + PROP_CANDLESTICKCHARTTYPE_SHOW_HIGH_LOW +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "Japanese", + PROP_CANDLESTICKCHARTTYPE_JAPANESE, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + + rOutProperties.emplace_back( "WhiteDay", + PROP_CANDLESTICKCHARTTYPE_WHITE_DAY, + cppu::UnoType<beans::XPropertySet>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEVOID ); + rOutProperties.emplace_back( "BlackDay", + PROP_CANDLESTICKCHARTTYPE_BLACK_DAY, + cppu::UnoType<beans::XPropertySet>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEVOID ); + + rOutProperties.emplace_back( "ShowFirst", + PROP_CANDLESTICKCHARTTYPE_SHOW_FIRST, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "ShowHighLow", + PROP_CANDLESTICKCHARTTYPE_SHOW_HIGH_LOW, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticCandleStickChartTypeDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + // must match default in CTOR! + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CANDLESTICKCHARTTYPE_JAPANESE, false ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CANDLESTICKCHARTTYPE_SHOW_FIRST, false ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_CANDLESTICKCHARTTYPE_SHOW_HIGH_LOW, true ); + } +}; + +struct StaticCandleStickChartTypeDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticCandleStickChartTypeDefaults_Initializer > +{ +}; + +struct StaticCandleStickChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticCandleStickChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticCandleStickChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticCandleStickChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticCandleStickChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticCandleStickChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticCandleStickChartTypeInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +CandleStickChartType::CandleStickChartType() +{ + Reference< beans::XPropertySet > xWhiteDayProps( new ::chart::StockBar( true )); + Reference< beans::XPropertySet > xBlackDayProps( new ::chart::StockBar( false )); + + ModifyListenerHelper::addListener( xWhiteDayProps, m_xModifyEventForwarder ); + ModifyListenerHelper::addListener( xBlackDayProps, m_xModifyEventForwarder ); + + setFastPropertyValue_NoBroadcast( + PROP_CANDLESTICKCHARTTYPE_WHITE_DAY, uno::Any( xWhiteDayProps )); + setFastPropertyValue_NoBroadcast( + PROP_CANDLESTICKCHARTTYPE_BLACK_DAY, uno::Any( xBlackDayProps )); +} + +CandleStickChartType::CandleStickChartType( const CandleStickChartType & rOther ) : + ChartType( rOther ) +{ + Reference< beans::XPropertySet > xPropertySet; + uno::Any aValue; + + getFastPropertyValue( aValue, PROP_CANDLESTICKCHARTTYPE_WHITE_DAY ); + if( ( aValue >>= xPropertySet ) + && xPropertySet.is()) + ModifyListenerHelper::addListener( xPropertySet, m_xModifyEventForwarder ); + + getFastPropertyValue( aValue, PROP_CANDLESTICKCHARTTYPE_BLACK_DAY ); + if( ( aValue >>= xPropertySet ) + && xPropertySet.is()) + ModifyListenerHelper::addListener( xPropertySet, m_xModifyEventForwarder ); +} + +CandleStickChartType::~CandleStickChartType() +{ + try + { + Reference< beans::XPropertySet > xPropertySet; + uno::Any aValue; + + getFastPropertyValue( aValue, PROP_CANDLESTICKCHARTTYPE_WHITE_DAY ); + if( ( aValue >>= xPropertySet ) + && xPropertySet.is()) + ModifyListenerHelper::removeListener( xPropertySet, m_xModifyEventForwarder ); + + getFastPropertyValue( aValue, PROP_CANDLESTICKCHARTTYPE_BLACK_DAY ); + if( ( aValue >>= xPropertySet ) + && xPropertySet.is()) + ModifyListenerHelper::removeListener( xPropertySet, m_xModifyEventForwarder ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL CandleStickChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new CandleStickChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL CandleStickChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK; +} + +uno::Sequence< OUString > SAL_CALL CandleStickChartType::getSupportedMandatoryRoles() +{ + bool bShowFirst = true; + bool bShowHiLow = false; + getFastPropertyValue( PROP_CANDLESTICKCHARTTYPE_SHOW_FIRST ) >>= bShowFirst; + getFastPropertyValue( PROP_CANDLESTICKCHARTTYPE_SHOW_HIGH_LOW ) >>= bShowHiLow; + + std::vector< OUString > aMandRoles; + + aMandRoles.emplace_back("label"); + if( bShowFirst ) + aMandRoles.emplace_back("values-first"); + + if( bShowHiLow ) + { + aMandRoles.emplace_back("values-min"); + aMandRoles.emplace_back("values-max"); + } + + aMandRoles.emplace_back("values-last"); + + return comphelper::containerToSequence( aMandRoles ); +} + +Sequence< OUString > SAL_CALL CandleStickChartType::getSupportedOptionalRoles() +{ + bool bShowFirst = true; + bool bShowHiLow = false; + getFastPropertyValue( PROP_CANDLESTICKCHARTTYPE_SHOW_FIRST ) >>= bShowFirst; + getFastPropertyValue( PROP_CANDLESTICKCHARTTYPE_SHOW_HIGH_LOW ) >>= bShowHiLow; + + std::vector< OUString > aOptRoles; + + if( ! bShowFirst ) + aOptRoles.emplace_back("values-first"); + + if( ! bShowHiLow ) + { + aOptRoles.emplace_back("values-min"); + aOptRoles.emplace_back("values-max"); + } + + return comphelper::containerToSequence( aOptRoles ); +} + +OUString SAL_CALL CandleStickChartType::getRoleOfSequenceForSeriesLabel() +{ + return "values-last"; +} + +// ____ OPropertySet ____ +uno::Any CandleStickChartType::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticCandleStickChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL CandleStickChartType::getInfoHelper() +{ + return *StaticCandleStickChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +Reference< beans::XPropertySetInfo > SAL_CALL CandleStickChartType::getPropertySetInfo() +{ + return *StaticCandleStickChartTypeInfo::get(); +} + +void SAL_CALL CandleStickChartType::setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, const uno::Any& rValue ) +{ + if( nHandle == PROP_CANDLESTICKCHARTTYPE_WHITE_DAY + || nHandle == PROP_CANDLESTICKCHARTTYPE_BLACK_DAY ) + { + uno::Any aOldValue; + Reference< util::XModifyBroadcaster > xBroadcaster; + getFastPropertyValue( aOldValue, nHandle ); + if( aOldValue.hasValue() && + (aOldValue >>= xBroadcaster) && + xBroadcaster.is()) + { + ModifyListenerHelper::removeListener( xBroadcaster, m_xModifyEventForwarder ); + } + + OSL_ASSERT( rValue.getValueType().getTypeClass() == uno::TypeClass_INTERFACE ); + if( rValue.hasValue() && + (rValue >>= xBroadcaster) && + xBroadcaster.is()) + { + ModifyListenerHelper::addListener( xBroadcaster, m_xModifyEventForwarder ); + } + } + + ::property::OPropertySet::setFastPropertyValue_NoBroadcast( nHandle, rValue ); +} + +OUString SAL_CALL CandleStickChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.CandleStickChartType" ; +} + +sal_Bool SAL_CALL CandleStickChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL CandleStickChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK, + "com.sun.star.chart2.ChartType", + "com.sun.star.beans.PropertySet" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_CandleStickChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::CandleStickChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/CandleStickChartType.hxx b/chart2/source/model/template/CandleStickChartType.hxx new file mode 100644 index 000000000..b3f8d37ec --- /dev/null +++ b/chart2/source/model/template/CandleStickChartType.hxx @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CANDLESTICKCHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CANDLESTICKCHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class CandleStickChartType final : public ChartType +{ +public: + explicit CandleStickChartType(); + virtual ~CandleStickChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit CandleStickChartType( const CandleStickChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedMandatoryRoles() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedOptionalRoles() override; + virtual OUString SAL_CALL getRoleOfSequenceForSeriesLabel() override; + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + + // ____ OPropertySet ____ + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ OPropertySet ____ + virtual void SAL_CALL setFastPropertyValue_NoBroadcast + ( sal_Int32 nHandle, + const css::uno::Any& rValue ) override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CANDLESTICKCHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ChartType.cxx b/chart2/source/model/template/ChartType.cxx new file mode 100644 index 000000000..999f7c1ed --- /dev/null +++ b/chart2/source/model/template/ChartType.cxx @@ -0,0 +1,308 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ChartType.hxx" +#include <CartesianCoordinateSystem.hxx> +#include <AxisHelper.hxx> +#include <CloneHelper.hxx> +#include <AxisIndexDefines.hxx> +#include <ModifyListenerHelper.hxx> +#include <vcl/svapp.hxx> +#include <com/sun/star/chart2/AxisType.hpp> +#include <com/sun/star/container/NoSuchElementException.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace chart +{ + +ChartType::ChartType() : + ::property::OPropertySet( m_aMutex ), + m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()), + m_bNotifyChanges( true ) +{} + +ChartType::ChartType( const ChartType & rOther ) : + impl::ChartType_Base(rOther), + ::property::OPropertySet( rOther, m_aMutex ), + m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()), + m_bNotifyChanges( true ) +{ + { + SolarMutexGuard g; // access to rOther.m_aDataSeries + CloneHelper::CloneRefVector<css::chart2::XDataSeries>( + rOther.m_aDataSeries, m_aDataSeries); + } + ModifyListenerHelper::addListenerToAllElements( m_aDataSeries, m_xModifyEventForwarder ); +} + +ChartType::~ChartType() +{ + ModifyListenerHelper::removeListenerFromAllElements( m_aDataSeries, m_xModifyEventForwarder ); + m_aDataSeries.clear(); +} + +// ____ XChartType ____ +Reference< chart2::XCoordinateSystem > SAL_CALL + ChartType::createCoordinateSystem( ::sal_Int32 DimensionCount ) +{ + Reference< chart2::XCoordinateSystem > xResult( + new CartesianCoordinateSystem( DimensionCount )); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + Reference< chart2::XAxis > xAxis( xResult->getAxisByDimension( i, MAIN_AXIS_INDEX ) ); + if( !xAxis.is() ) + { + OSL_FAIL("a created coordinate system should have an axis for each dimension"); + continue; + } + + chart2::ScaleData aScaleData = xAxis->getScaleData(); + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + aScaleData.Scaling = AxisHelper::createLinearScaling(); + + switch( i ) + { + case 0: aScaleData.AxisType = chart2::AxisType::CATEGORY; break; + case 2: aScaleData.AxisType = chart2::AxisType::SERIES; break; + default: aScaleData.AxisType = chart2::AxisType::REALNUMBER; break; + } + + xAxis->setScaleData( aScaleData ); + } + + return xResult; +} + +Sequence< OUString > SAL_CALL ChartType::getSupportedMandatoryRoles() +{ + Sequence< OUString > aDefaultSeq(2); + aDefaultSeq[0] = "label"; + aDefaultSeq[1] = "values-y"; + return aDefaultSeq; +} + +Sequence< OUString > SAL_CALL ChartType::getSupportedOptionalRoles() +{ + return Sequence< OUString >(); +} + +Sequence< OUString > SAL_CALL ChartType::getSupportedPropertyRoles() +{ + return Sequence< OUString >(); +} + +OUString SAL_CALL ChartType::getRoleOfSequenceForSeriesLabel() +{ + return "values-y"; +} + +void ChartType::impl_addDataSeriesWithoutNotification( + const Reference< chart2::XDataSeries >& xDataSeries ) +{ + if( std::find( m_aDataSeries.begin(), m_aDataSeries.end(), xDataSeries ) + != m_aDataSeries.end()) + throw lang::IllegalArgumentException(); + + m_aDataSeries.push_back( xDataSeries ); + ModifyListenerHelper::addListener( xDataSeries, m_xModifyEventForwarder ); +} + +// ____ XDataSeriesContainer ____ +void SAL_CALL ChartType::addDataSeries( const Reference< chart2::XDataSeries >& xDataSeries ) +{ + SolarMutexGuard g; + + impl_addDataSeriesWithoutNotification( xDataSeries ); + fireModifyEvent(); +} + +void SAL_CALL ChartType::removeDataSeries( const Reference< chart2::XDataSeries >& xDataSeries ) +{ + if( !xDataSeries.is()) + throw container::NoSuchElementException(); + + SolarMutexGuard g; + + tDataSeriesContainerType::iterator aIt( + std::find( m_aDataSeries.begin(), m_aDataSeries.end(), xDataSeries ) ); + + if( aIt == m_aDataSeries.end()) + throw container::NoSuchElementException( + "The given series is no element of this charttype", + static_cast< uno::XWeak * >( this )); + + ModifyListenerHelper::removeListener( xDataSeries, m_xModifyEventForwarder ); + m_aDataSeries.erase( aIt ); + fireModifyEvent(); +} + +Sequence< Reference< chart2::XDataSeries > > SAL_CALL ChartType::getDataSeries() +{ + SolarMutexGuard g; + + return comphelper::containerToSequence( m_aDataSeries ); +} + +void SAL_CALL ChartType::setDataSeries( const Sequence< Reference< chart2::XDataSeries > >& aDataSeries ) +{ + SolarMutexGuard g; + + m_bNotifyChanges = false; + try + { + const Sequence< Reference< chart2::XDataSeries > > aOldSeries( getDataSeries() ); + for( auto const & i : aOldSeries ) + ModifyListenerHelper::removeListener( i, m_xModifyEventForwarder ); + m_aDataSeries.clear(); + + for( auto const & i : aDataSeries ) + impl_addDataSeriesWithoutNotification( i ); + } + catch( ... ) + { + m_bNotifyChanges = true; + throw; + } + m_bNotifyChanges = true; + fireModifyEvent(); +} + +// ____ OPropertySet ____ +uno::Any ChartType::GetDefaultValue( sal_Int32 /* nHandle */ ) const +{ + return uno::Any(); +} + +namespace +{ + +struct StaticChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( Sequence< beans::Property >{} ); + return &aPropHelper; + } +}; + +struct StaticChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticChartTypeInfo_Initializer > +{ +}; + +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL ChartType::getInfoHelper() +{ + return *StaticChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ChartType::getPropertySetInfo() +{ + return *StaticChartTypeInfo::get(); +} + +// ____ XModifyBroadcaster ____ +void SAL_CALL ChartType::addModifyListener( const uno::Reference< util::XModifyListener >& aListener ) +{ + try + { + uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); + xBroadcaster->addModifyListener( aListener ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void SAL_CALL ChartType::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener ) +{ + try + { + uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); + xBroadcaster->removeModifyListener( aListener ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ XModifyListener ____ +void SAL_CALL ChartType::modified( const lang::EventObject& aEvent ) +{ + m_xModifyEventForwarder->modified( aEvent ); +} + +// ____ XEventListener (base of XModifyListener) ____ +void SAL_CALL ChartType::disposing( const lang::EventObject& /* Source */ ) +{ + // nothing +} + +// ____ OPropertySet ____ +void ChartType::firePropertyChangeEvent() +{ + fireModifyEvent(); +} + +void ChartType::fireModifyEvent() +{ + bool bNotifyChanges; + + { + SolarMutexGuard g; + bNotifyChanges = m_bNotifyChanges; + } + + if (bNotifyChanges) + m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this ))); +} + +using impl::ChartType_Base; + +IMPLEMENT_FORWARD_XINTERFACE2( ChartType, ChartType_Base, ::property::OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( ChartType, ChartType_Base, ::property::OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ChartType.hxx b/chart2/source/model/template/ChartType.hxx new file mode 100644 index 000000000..3274d5660 --- /dev/null +++ b/chart2/source/model/template/ChartType.hxx @@ -0,0 +1,141 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CHARTTYPE_HXX + +#include <MutexContainer.hxx> +#include <OPropertySet.hxx> +#include <cppuhelper/implbase.hxx> +#include <comphelper/uno3.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/chart2/XChartType.hpp> +#include <com/sun/star/chart2/XDataSeriesContainer.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/util/XModifyBroadcaster.hpp> +#include <com/sun/star/util/XModifyListener.hpp> + +#include <vector> + +namespace chart +{ + +namespace impl +{ +typedef ::cppu::WeakImplHelper< + css::lang::XServiceInfo, + css::chart2::XChartType, + css::chart2::XDataSeriesContainer, + css::util::XCloneable, + css::util::XModifyBroadcaster, + css::util::XModifyListener > + ChartType_Base; +} + +class ChartType : + public MutexContainer, + public impl::ChartType_Base, + public ::property::OPropertySet +{ +public: + explicit ChartType(); + virtual ~ChartType() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + +protected: + explicit ChartType( const ChartType & rOther ); + + // ____ XChartType ____ + // still abstract ! implement ! + virtual OUString SAL_CALL getChartType() override = 0; + virtual css::uno::Reference< css::chart2::XCoordinateSystem > SAL_CALL + createCoordinateSystem( ::sal_Int32 DimensionCount ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedMandatoryRoles() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedOptionalRoles() override; + virtual OUString SAL_CALL getRoleOfSequenceForSeriesLabel() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedPropertyRoles() override; + + // ____ XDataSeriesContainer ____ + virtual void SAL_CALL addDataSeries( + const css::uno::Reference< css::chart2::XDataSeries >& aDataSeries ) override; + virtual void SAL_CALL removeDataSeries( + const css::uno::Reference< css::chart2::XDataSeries >& aDataSeries ) override; + virtual css::uno::Sequence< css::uno::Reference< css::chart2::XDataSeries > > SAL_CALL getDataSeries() override; + virtual void SAL_CALL setDataSeries( + const css::uno::Sequence< css::uno::Reference< css::chart2::XDataSeries > >& aDataSeries ) override; + + // ____ XModifyBroadcaster ____ + virtual void SAL_CALL addModifyListener( + const css::uno::Reference< css::util::XModifyListener >& aListener ) override; + virtual void SAL_CALL removeModifyListener( + const css::uno::Reference< css::util::XModifyListener >& aListener ) override; + + // ____ XModifyListener ____ + virtual void SAL_CALL modified( + const css::lang::EventObject& aEvent ) override; + + // ____ XEventListener (base of XModifyListener) ____ + virtual void SAL_CALL disposing( + const css::lang::EventObject& Source ) override; + + void fireModifyEvent(); + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + virtual void firePropertyChangeEvent() override; + using OPropertySet::disposing; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + css::uno::Reference< css::util::XModifyListener > + const m_xModifyEventForwarder; + +private: + void impl_addDataSeriesWithoutNotification( + const css::uno::Reference< css::chart2::XDataSeries >& aDataSeries ); + +private: + typedef + std::vector< css::uno::Reference< css::chart2::XDataSeries > > tDataSeriesContainerType; + + // --- mutable members: the following members need mutex guard --- + + tDataSeriesContainerType m_aDataSeries; + + bool m_bNotifyChanges; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ChartTypeManager.cxx b/chart2/source/model/template/ChartTypeManager.cxx new file mode 100644 index 000000000..c0bcc0a03 --- /dev/null +++ b/chart2/source/model/template/ChartTypeManager.cxx @@ -0,0 +1,606 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ChartTypeManager.hxx> +#include <StackMode.hxx> + +#include "LineChartTypeTemplate.hxx" +#include "BarChartTypeTemplate.hxx" +#include "ColumnLineChartTypeTemplate.hxx" +#include "AreaChartTypeTemplate.hxx" +#include "PieChartTypeTemplate.hxx" +#include "ScatterChartTypeTemplate.hxx" +#include "StockChartTypeTemplate.hxx" +#include "NetChartTypeTemplate.hxx" +#include "BubbleChartTypeTemplate.hxx" +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/lang/XServiceName.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <tools/diagnose_ex.h> +#include <sal/log.hxx> + +#include <algorithm> +#include <iterator> +#include <o3tl/functional.hxx> +#include <map> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Sequence; + +namespace +{ + +enum TemplateId +{ + TEMPLATE_SYMBOL, + TEMPLATE_STACKEDSYMBOL, + TEMPLATE_PERCENTSTACKEDSYMBOL, + TEMPLATE_LINE, + TEMPLATE_STACKEDLINE, + TEMPLATE_PERCENTSTACKEDLINE, + TEMPLATE_LINESYMBOL, + TEMPLATE_STACKEDLINESYMBOL, + TEMPLATE_PERCENTSTACKEDLINESYMBOL, + TEMPLATE_THREEDLINE, + TEMPLATE_STACKEDTHREEDLINE, + TEMPLATE_PERCENTSTACKEDTHREEDLINE, + TEMPLATE_THREEDLINEDEEP, + TEMPLATE_COLUMN, + TEMPLATE_STACKEDCOLUMN, + TEMPLATE_PERCENTSTACKEDCOLUMN, + TEMPLATE_BAR, + TEMPLATE_STACKEDBAR, + TEMPLATE_PERCENTSTACKEDBAR, + TEMPLATE_THREEDCOLUMNDEEP, + TEMPLATE_THREEDCOLUMNFLAT, + TEMPLATE_STACKEDTHREEDCOLUMNFLAT, + TEMPLATE_PERCENTSTACKEDTHREEDCOLUMNFLAT, + TEMPLATE_THREEDBARDEEP, + TEMPLATE_THREEDBARFLAT, + TEMPLATE_STACKEDTHREEDBARFLAT, + TEMPLATE_PERCENTSTACKEDTHREEDBARFLAT, + TEMPLATE_COLUMNWITHLINE, + TEMPLATE_STACKEDCOLUMNWITHLINE, + TEMPLATE_AREA, + TEMPLATE_STACKEDAREA, + TEMPLATE_PERCENTSTACKEDAREA, + TEMPLATE_THREEDAREA, + TEMPLATE_STACKEDTHREEDAREA, + TEMPLATE_PERCENTSTACKEDTHREEDAREA, + TEMPLATE_PIE, + TEMPLATE_PIEALLEXPLODED, + TEMPLATE_DONUT, + TEMPLATE_DONUTALLEXPLODED, + TEMPLATE_THREEDPIE, + TEMPLATE_THREEDPIEALLEXPLODED, + TEMPLATE_THREEDDONUT, + TEMPLATE_THREEDDONUTALLEXPLODED, + TEMPLATE_SCATTERLINESYMBOL, + TEMPLATE_SCATTERLINE, + TEMPLATE_SCATTERSYMBOL, + TEMPLATE_THREEDSCATTER, + TEMPLATE_NET, + TEMPLATE_NETSYMBOL, + TEMPLATE_NETLINE, + TEMPLATE_STACKEDNET, + TEMPLATE_STACKEDNETSYMBOL, + TEMPLATE_STACKEDNETLINE, + TEMPLATE_PERCENTSTACKEDNET, + TEMPLATE_PERCENTSTACKEDNETSYMBOL, + TEMPLATE_PERCENTSTACKEDNETLINE, + TEMPLATE_FILLEDNET, + TEMPLATE_STACKEDFILLEDNET, + TEMPLATE_PERCENTSTACKEDFILLEDNET, + TEMPLATE_STOCKLOWHIGHCLOSE, + TEMPLATE_STOCKOPENLOWHIGHCLOSE, + TEMPLATE_STOCKVOLUMELOWHIGHCLOSE, + TEMPLATE_STOCKVOLUMEOPENLOWHIGHCLOSE, + TEMPLATE_BUBBLE, +// TEMPLATE_SURFACE, +// TEMPLATE_ADDIN, + TEMPLATE_NOT_FOUND = 0xffff +}; + +typedef std::map< OUString, TemplateId > tTemplateMapType; + +const tTemplateMapType & lcl_DefaultChartTypeMap() +{ + static const tTemplateMapType aMap{ + {"com.sun.star.chart2.template.Symbol", TEMPLATE_SYMBOL}, + {"com.sun.star.chart2.template.StackedSymbol", TEMPLATE_STACKEDSYMBOL}, + {"com.sun.star.chart2.template.PercentStackedSymbol", TEMPLATE_PERCENTSTACKEDSYMBOL}, + {"com.sun.star.chart2.template.Line", TEMPLATE_LINE}, + {"com.sun.star.chart2.template.StackedLine", TEMPLATE_STACKEDLINE}, + {"com.sun.star.chart2.template.PercentStackedLine", TEMPLATE_PERCENTSTACKEDLINE}, + {"com.sun.star.chart2.template.LineSymbol", TEMPLATE_LINESYMBOL}, + {"com.sun.star.chart2.template.StackedLineSymbol", TEMPLATE_STACKEDLINESYMBOL}, + {"com.sun.star.chart2.template.PercentStackedLineSymbol", TEMPLATE_PERCENTSTACKEDLINESYMBOL}, + {"com.sun.star.chart2.template.ThreeDLine", TEMPLATE_THREEDLINE}, + {"com.sun.star.chart2.template.StackedThreeDLine", TEMPLATE_STACKEDTHREEDLINE}, + {"com.sun.star.chart2.template.PercentStackedThreeDLine", TEMPLATE_PERCENTSTACKEDTHREEDLINE}, + {"com.sun.star.chart2.template.ThreeDLineDeep", TEMPLATE_THREEDLINEDEEP}, + {"com.sun.star.chart2.template.Column", TEMPLATE_COLUMN}, + {"com.sun.star.chart2.template.StackedColumn", TEMPLATE_STACKEDCOLUMN}, + {"com.sun.star.chart2.template.PercentStackedColumn", TEMPLATE_PERCENTSTACKEDCOLUMN}, + {"com.sun.star.chart2.template.Bar", TEMPLATE_BAR}, + {"com.sun.star.chart2.template.StackedBar", TEMPLATE_STACKEDBAR}, + {"com.sun.star.chart2.template.PercentStackedBar", TEMPLATE_PERCENTSTACKEDBAR}, + {"com.sun.star.chart2.template.ThreeDColumnDeep", TEMPLATE_THREEDCOLUMNDEEP}, + {"com.sun.star.chart2.template.ThreeDColumnFlat", TEMPLATE_THREEDCOLUMNFLAT}, + {"com.sun.star.chart2.template.StackedThreeDColumnFlat", TEMPLATE_STACKEDTHREEDCOLUMNFLAT}, + {"com.sun.star.chart2.template.PercentStackedThreeDColumnFlat", TEMPLATE_PERCENTSTACKEDTHREEDCOLUMNFLAT}, + {"com.sun.star.chart2.template.ThreeDBarDeep", TEMPLATE_THREEDBARDEEP}, + {"com.sun.star.chart2.template.ThreeDBarFlat", TEMPLATE_THREEDBARFLAT}, + {"com.sun.star.chart2.template.StackedThreeDBarFlat", TEMPLATE_STACKEDTHREEDBARFLAT}, + {"com.sun.star.chart2.template.PercentStackedThreeDBarFlat", TEMPLATE_PERCENTSTACKEDTHREEDBARFLAT}, + {"com.sun.star.chart2.template.ColumnWithLine", TEMPLATE_COLUMNWITHLINE}, + {"com.sun.star.chart2.template.StackedColumnWithLine", TEMPLATE_STACKEDCOLUMNWITHLINE}, + {"com.sun.star.chart2.template.Area", TEMPLATE_AREA}, + {"com.sun.star.chart2.template.StackedArea", TEMPLATE_STACKEDAREA}, + {"com.sun.star.chart2.template.PercentStackedArea", TEMPLATE_PERCENTSTACKEDAREA}, + {"com.sun.star.chart2.template.ThreeDArea", TEMPLATE_THREEDAREA}, + {"com.sun.star.chart2.template.StackedThreeDArea", TEMPLATE_STACKEDTHREEDAREA}, + {"com.sun.star.chart2.template.PercentStackedThreeDArea", TEMPLATE_PERCENTSTACKEDTHREEDAREA}, + {"com.sun.star.chart2.template.Pie", TEMPLATE_PIE}, + {"com.sun.star.chart2.template.PieAllExploded", TEMPLATE_PIEALLEXPLODED}, + {"com.sun.star.chart2.template.Donut", TEMPLATE_DONUT}, + {"com.sun.star.chart2.template.DonutAllExploded", TEMPLATE_DONUTALLEXPLODED}, + {"com.sun.star.chart2.template.ThreeDPie", TEMPLATE_THREEDPIE}, + {"com.sun.star.chart2.template.ThreeDPieAllExploded", TEMPLATE_THREEDPIEALLEXPLODED}, + {"com.sun.star.chart2.template.ThreeDDonut", TEMPLATE_THREEDDONUT}, + {"com.sun.star.chart2.template.ThreeDDonutAllExploded", TEMPLATE_THREEDDONUTALLEXPLODED}, + {"com.sun.star.chart2.template.ScatterLineSymbol", TEMPLATE_SCATTERLINESYMBOL}, + {"com.sun.star.chart2.template.ScatterLine", TEMPLATE_SCATTERLINE}, + {"com.sun.star.chart2.template.ScatterSymbol", TEMPLATE_SCATTERSYMBOL}, + {"com.sun.star.chart2.template.ThreeDScatter", TEMPLATE_THREEDSCATTER}, + {"com.sun.star.chart2.template.Net", TEMPLATE_NET}, + {"com.sun.star.chart2.template.NetSymbol", TEMPLATE_NETSYMBOL}, + {"com.sun.star.chart2.template.NetLine", TEMPLATE_NETLINE}, + {"com.sun.star.chart2.template.StackedNet", TEMPLATE_STACKEDNET}, + {"com.sun.star.chart2.template.StackedNetSymbol", TEMPLATE_STACKEDNETSYMBOL}, + {"com.sun.star.chart2.template.StackedNetLine", TEMPLATE_STACKEDNETLINE}, + {"com.sun.star.chart2.template.PercentStackedNet", TEMPLATE_PERCENTSTACKEDNET}, + {"com.sun.star.chart2.template.PercentStackedNetSymbol", TEMPLATE_PERCENTSTACKEDNETSYMBOL}, + {"com.sun.star.chart2.template.PercentStackedNetLine", TEMPLATE_PERCENTSTACKEDNETLINE}, + {"com.sun.star.chart2.template.FilledNet", TEMPLATE_FILLEDNET}, + {"com.sun.star.chart2.template.StackedFilledNet", TEMPLATE_STACKEDFILLEDNET}, + {"com.sun.star.chart2.template.PercentStackedFilledNet", TEMPLATE_PERCENTSTACKEDFILLEDNET}, + {"com.sun.star.chart2.template.StockLowHighClose", TEMPLATE_STOCKLOWHIGHCLOSE}, + {"com.sun.star.chart2.template.StockOpenLowHighClose", TEMPLATE_STOCKOPENLOWHIGHCLOSE}, + {"com.sun.star.chart2.template.StockVolumeLowHighClose", TEMPLATE_STOCKVOLUMELOWHIGHCLOSE}, + {"com.sun.star.chart2.template.StockVolumeOpenLowHighClose", TEMPLATE_STOCKVOLUMEOPENLOWHIGHCLOSE}, + {"com.sun.star.chart2.template.Bubble", TEMPLATE_BUBBLE}, +// {"com.sun.star.chart2.template.Surface", TEMPLATE_SURFACE}, +// {"com.sun.star.chart2.template.Addin", TEMPLATE_ADDIN}, + }; + return aMap; +} + +TemplateId lcl_GetTemplateIdForService( const OUString & rServiceName ) +{ + TemplateId eResult = TEMPLATE_NOT_FOUND; + const tTemplateMapType & rMap = lcl_DefaultChartTypeMap(); + tTemplateMapType::const_iterator aIt( rMap.find( rServiceName )); + + if( aIt != rMap.end()) + eResult = (*aIt).second; + + return eResult; +} + +} // anonymous namespace + +namespace chart +{ + +ChartTypeManager::ChartTypeManager( + uno::Reference< + uno::XComponentContext > const & xContext ) : + m_xContext( xContext ) +{} + +ChartTypeManager::~ChartTypeManager() +{} + +// ____ XMultiServiceFactory ____ +uno::Reference< uno::XInterface > SAL_CALL ChartTypeManager::createInstance( + const OUString& aServiceSpecifier ) +{ + uno::Reference< uno::XInterface > xResult; + TemplateId nId = lcl_GetTemplateIdForService( aServiceSpecifier ); + + if( nId == TEMPLATE_NOT_FOUND ) + { + try + { + xResult = m_xContext->getServiceManager()->createInstanceWithContext( + aServiceSpecifier, m_xContext ); + } +// catch( registry::InvalidValueException & ex ) + catch( const uno::Exception & ) + { + // couldn't create service via factory + + // As XMultiServiceFactory does not specify, what to do in case + // createInstance is called with an unknown service-name, this + // function will just return an empty XInterface. + DBG_UNHANDLED_EXCEPTION("chart2"); + SAL_WARN("chart2", "Couldn't instantiate service: "<< aServiceSpecifier ); + xResult.set( nullptr ); + } + } + else + { + uno::Reference< chart2::XChartTypeTemplate > xTemplate; + switch( nId ) + { + // Point (category x axis) + case TEMPLATE_SYMBOL: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, true, false )); + break; + case TEMPLATE_STACKEDSYMBOL: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, true, false )); + break; + case TEMPLATE_PERCENTSTACKEDSYMBOL: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, true, false )); + break; + // Line (category x axis) + case TEMPLATE_LINE: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, false )); + break; + case TEMPLATE_STACKEDLINE: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, false )); + break; + case TEMPLATE_PERCENTSTACKEDLINE: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, false )); + break; + case TEMPLATE_LINESYMBOL: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, true )); + break; + case TEMPLATE_STACKEDLINESYMBOL: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, true )); + break; + case TEMPLATE_PERCENTSTACKEDLINESYMBOL: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, true )); + break; + case TEMPLATE_THREEDLINE: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, false, true, 3 )); + break; + case TEMPLATE_STACKEDTHREEDLINE: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, false, true, 3 )); + break; + case TEMPLATE_PERCENTSTACKEDTHREEDLINE: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, false, true, 3 )); + break; + case TEMPLATE_THREEDLINEDEEP: + xTemplate.set( new LineChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::ZStacked, false, true, 3 )); + break; + + // Bar/Column + case TEMPLATE_COLUMN: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, BarChartTypeTemplate::VERTICAL )); + break; + case TEMPLATE_STACKEDCOLUMN: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, BarChartTypeTemplate::VERTICAL )); + break; + case TEMPLATE_PERCENTSTACKEDCOLUMN: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, BarChartTypeTemplate::VERTICAL )); + break; + case TEMPLATE_BAR: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, BarChartTypeTemplate::HORIZONTAL )); + break; + case TEMPLATE_STACKEDBAR: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, BarChartTypeTemplate::HORIZONTAL )); + break; + case TEMPLATE_PERCENTSTACKEDBAR: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, BarChartTypeTemplate::HORIZONTAL )); + break; + case TEMPLATE_THREEDCOLUMNDEEP: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::ZStacked, BarChartTypeTemplate::VERTICAL, 3 )); + break; + case TEMPLATE_THREEDCOLUMNFLAT: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, BarChartTypeTemplate::VERTICAL, 3 )); + break; + case TEMPLATE_STACKEDTHREEDCOLUMNFLAT: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, BarChartTypeTemplate::VERTICAL, 3 )); + break; + case TEMPLATE_PERCENTSTACKEDTHREEDCOLUMNFLAT: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, BarChartTypeTemplate::VERTICAL, 3 )); + break; + case TEMPLATE_THREEDBARDEEP: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::ZStacked, BarChartTypeTemplate::HORIZONTAL, 3 )); + break; + case TEMPLATE_THREEDBARFLAT: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, BarChartTypeTemplate::HORIZONTAL, 3 )); + break; + case TEMPLATE_STACKEDTHREEDBARFLAT: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, BarChartTypeTemplate::HORIZONTAL, 3 )); + break; + case TEMPLATE_PERCENTSTACKEDTHREEDBARFLAT: + xTemplate.set( new BarChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, BarChartTypeTemplate::HORIZONTAL, 3 )); + break; + + // Combi-Chart Line/Column + case TEMPLATE_COLUMNWITHLINE: + case TEMPLATE_STACKEDCOLUMNWITHLINE: + { + StackMode eMode = ( nId == TEMPLATE_COLUMNWITHLINE ) + ? StackMode::NONE + : StackMode::YStacked; + + xTemplate.set( new ColumnLineChartTypeTemplate( m_xContext, aServiceSpecifier, eMode, 1 )); + } + break; + + // Area + case TEMPLATE_AREA: + xTemplate.set( new AreaChartTypeTemplate( m_xContext, aServiceSpecifier, StackMode::NONE )); + break; + case TEMPLATE_STACKEDAREA: + xTemplate.set( new AreaChartTypeTemplate( m_xContext, aServiceSpecifier, StackMode::YStacked )); + break; + case TEMPLATE_PERCENTSTACKEDAREA: + xTemplate.set( new AreaChartTypeTemplate( m_xContext, aServiceSpecifier, StackMode::YStackedPercent )); + break; + case TEMPLATE_THREEDAREA: + xTemplate.set( new AreaChartTypeTemplate( m_xContext, aServiceSpecifier, StackMode::ZStacked, 3 )); + break; + case TEMPLATE_STACKEDTHREEDAREA: + xTemplate.set( new AreaChartTypeTemplate( m_xContext, aServiceSpecifier, StackMode::YStacked, 3 )); + break; + case TEMPLATE_PERCENTSTACKEDTHREEDAREA: + xTemplate.set( new AreaChartTypeTemplate( m_xContext, aServiceSpecifier, StackMode::YStackedPercent, 3 )); + break; + + case TEMPLATE_PIE: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_NONE, false )); + break; + case TEMPLATE_PIEALLEXPLODED: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_ALL_EXPLODED, false )); + break; + case TEMPLATE_DONUT: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_NONE, true )); + break; + case TEMPLATE_DONUTALLEXPLODED: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_ALL_EXPLODED, true )); + break; + case TEMPLATE_THREEDPIE: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_NONE, false, 3 )); + break; + case TEMPLATE_THREEDPIEALLEXPLODED: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_ALL_EXPLODED, false, 3 )); + break; + case TEMPLATE_THREEDDONUT: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_NONE, true, 3 )); + break; + case TEMPLATE_THREEDDONUTALLEXPLODED: + xTemplate.set( new PieChartTypeTemplate( m_xContext, aServiceSpecifier, + chart2::PieChartOffsetMode_ALL_EXPLODED, true, 3 )); + break; + + case TEMPLATE_SCATTERLINESYMBOL: + xTemplate.set( new ScatterChartTypeTemplate( m_xContext, aServiceSpecifier, /* bSymbols */ true )); + break; + case TEMPLATE_SCATTERLINE: + xTemplate.set( new ScatterChartTypeTemplate( m_xContext, aServiceSpecifier, /* bSymbols */ false )); + break; + case TEMPLATE_SCATTERSYMBOL: + xTemplate.set( new ScatterChartTypeTemplate( m_xContext, aServiceSpecifier, /* bSymbols */ true, /* bHasLines */ false )); + break; + case TEMPLATE_THREEDSCATTER: + xTemplate.set( new ScatterChartTypeTemplate( m_xContext, aServiceSpecifier, /* bSymbols */ false, /* bHasLines */ true, 3 )); + break; + + // NetChart + case TEMPLATE_NET: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, true )); + break; + case TEMPLATE_NETSYMBOL: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, true, false )); + break; + case TEMPLATE_NETLINE: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, false )); + break; + + case TEMPLATE_STACKEDNET: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, true )); + break; + case TEMPLATE_STACKEDNETSYMBOL: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, true, false )); + break; + case TEMPLATE_STACKEDNETLINE: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, false, true )); + break; + + case TEMPLATE_PERCENTSTACKEDNET: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, true )); + break; + case TEMPLATE_PERCENTSTACKEDNETSYMBOL: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, true, false )); + break; + case TEMPLATE_PERCENTSTACKEDNETLINE: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, false, true )); + break; + + case TEMPLATE_FILLEDNET: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::NONE, false, false, true )); + break; + case TEMPLATE_STACKEDFILLEDNET: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStacked, false, false, true )); + break; + case TEMPLATE_PERCENTSTACKEDFILLEDNET: + xTemplate.set( new NetChartTypeTemplate( m_xContext, aServiceSpecifier, + StackMode::YStackedPercent, false, false, true )); + break; + + case TEMPLATE_STOCKLOWHIGHCLOSE: + xTemplate.set( new StockChartTypeTemplate( m_xContext, aServiceSpecifier, + StockChartTypeTemplate::StockVariant::NONE, false )); + break; + case TEMPLATE_STOCKOPENLOWHIGHCLOSE: + xTemplate.set( new StockChartTypeTemplate( m_xContext, aServiceSpecifier, + StockChartTypeTemplate::StockVariant::Open, true )); + break; + case TEMPLATE_STOCKVOLUMELOWHIGHCLOSE: + xTemplate.set( new StockChartTypeTemplate( m_xContext, aServiceSpecifier, + StockChartTypeTemplate::StockVariant::Volume, false )); + break; + case TEMPLATE_STOCKVOLUMEOPENLOWHIGHCLOSE: + xTemplate.set( new StockChartTypeTemplate( m_xContext, aServiceSpecifier, + StockChartTypeTemplate::StockVariant::VolumeOpen, true )); + break; + + //BubbleChart + case TEMPLATE_BUBBLE: + xTemplate.set( new BubbleChartTypeTemplate( m_xContext, aServiceSpecifier )); + break; + default: break; +// case TEMPLATE_SURFACE: +// case TEMPLATE_ADDIN: +// break; + + case TEMPLATE_NOT_FOUND: + OSL_ASSERT( false ); + break; + } + xResult.set( xTemplate, uno::UNO_QUERY ); + } + + return xResult; +} + +uno::Reference< uno::XInterface > SAL_CALL ChartTypeManager::createInstanceWithArguments( + const OUString& ServiceSpecifier, + const uno::Sequence< uno::Any >& /* Arguments */ ) +{ + OSL_FAIL( "createInstanceWithArguments: No arguments supported" ); + return createInstance( ServiceSpecifier ); +} + +uno::Sequence< OUString > SAL_CALL ChartTypeManager::getAvailableServiceNames() +{ + std::vector< OUString > aServices; + const tTemplateMapType & rMap = lcl_DefaultChartTypeMap(); + aServices.reserve( rMap.size()); + + // get own default templates + std::transform( rMap.begin(), rMap.end(), std::back_inserter( aServices ), + ::o3tl::select1st< tTemplateMapType::value_type >() ); + + // add components that were registered in the context's factory + uno::Reference< container::XContentEnumerationAccess > xEnumAcc( + m_xContext->getServiceManager(), uno::UNO_QUERY ); + if( xEnumAcc.is()) + { + uno::Reference< container::XEnumeration > xEnum( + xEnumAcc->createContentEnumeration( "com.sun.star.chart2.ChartTypeTemplate" )); + if( xEnum.is()) + { + uno::Reference< uno::XInterface > xFactIntf; + + while( xEnum->hasMoreElements()) + { + if( xEnum->nextElement() >>= xFactIntf ) + { + uno::Reference< lang::XServiceName > xServiceName( xFactIntf, uno::UNO_QUERY ); + if( xServiceName.is()) + aServices.push_back( xServiceName->getServiceName()); + } + } + } + } + + return comphelper::containerToSequence( aServices ); +} + +// ____ XServiceInfo ____ +OUString SAL_CALL ChartTypeManager::getImplementationName() +{ + return "com.sun.star.comp.chart.ChartTypeManager"; +} + +sal_Bool SAL_CALL ChartTypeManager::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL ChartTypeManager::getSupportedServiceNames() +{ + return { + "com.sun.star.chart2.ChartTypeManager", + "com.sun.star.lang.MultiServiceFactory" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_ChartTypeManager_get_implementation(css::uno::XComponentContext *context, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::ChartTypeManager(context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ChartTypeTemplate.cxx b/chart2/source/model/template/ChartTypeTemplate.cxx new file mode 100644 index 000000000..8aafc1fd1 --- /dev/null +++ b/chart2/source/model/template/ChartTypeTemplate.cxx @@ -0,0 +1,877 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ChartTypeTemplate.hxx" +#include "DataInterpreter.hxx" +#include <CommonConverters.hxx> +#include <ChartTypeHelper.hxx> + +#include <AxisHelper.hxx> +#include <DiagramHelper.hxx> +#include <AxisIndexDefines.hxx> +#include <unonames.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/chart2/AxisType.hpp> +#include <com/sun/star/chart2/StackingDirection.hpp> +#include <com/sun/star/chart2/XDataSeriesContainer.hpp> +#include <com/sun/star/chart2/XChartTypeContainer.hpp> +#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> +#include <tools/diagnose_ex.h> +#include <comphelper/property.hxx> +#include <comphelper/sequence.hxx> + +#include <algorithm> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; + +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace +{ + +void lcl_applyDefaultStyle( + const Reference< XDataSeries > & xSeries, + sal_Int32 nIndex, + const Reference< XDiagram > & xDiagram ) +{ + // @deprecated: correct default color should be found by view without + // setting color as hard attribute + if( xSeries.is() && xDiagram.is()) + { + Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY ); + Reference< chart2::XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme()); + if( xSeriesProp.is() && xColorScheme.is() ) + xSeriesProp->setPropertyValue( + "Color", + uno::Any( xColorScheme->getColorByIndex( nIndex ))); + } +} + +void lcl_ensureCorrectLabelPlacement( const Reference< beans::XPropertySet >& xProp, const uno::Sequence < sal_Int32 >& rAvailablePlacements ) +{ + sal_Int32 nLabelPlacement=0; + if( !(xProp.is() && (xProp->getPropertyValue( "LabelPlacement" ) >>= nLabelPlacement)) ) + return; + + bool bValid = false; + for( sal_Int32 i : rAvailablePlacements ) + { + if( i == nLabelPlacement ) + { + bValid = true; + break; + } + } + if( !bValid ) + { + uno::Any aNewValue; + //otherwise use the first supported one + if( rAvailablePlacements.hasElements() ) + aNewValue <<=rAvailablePlacements[0]; + xProp->setPropertyValue( "LabelPlacement", aNewValue ); + } +} + +void lcl_resetLabelPlacementIfDefault( const Reference< beans::XPropertySet >& xProp, sal_Int32 nDefaultPlacement ) +{ + + sal_Int32 nLabelPlacement=0; + if( xProp.is() && (xProp->getPropertyValue( "LabelPlacement" ) >>= nLabelPlacement) ) + { + if( nDefaultPlacement == nLabelPlacement ) + xProp->setPropertyValue( "LabelPlacement", uno::Any() ); + } +} + +void lcl_ensureCorrectMissingValueTreatment( const Reference< chart2::XDiagram >& xDiagram, const Reference< XChartType >& xChartType ) +{ + Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY ); + if( xDiaProp.is() ) + { + uno::Sequence < sal_Int32 > aAvailableMissingValueTreatment( + ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) ); + + if( aAvailableMissingValueTreatment.hasElements() ) + xDiaProp->setPropertyValue( "MissingValueTreatment", uno::Any( aAvailableMissingValueTreatment[0] ) ); + else + xDiaProp->setPropertyValue( "MissingValueTreatment", uno::Any() ); + } +} + +} // anonymous namespace + +namespace chart +{ + +ChartTypeTemplate::ChartTypeTemplate( + Reference< uno::XComponentContext > const & xContext, + const OUString & rServiceName ) : + m_xContext( xContext ), + m_aServiceName( rServiceName ) +{ +} + +ChartTypeTemplate::~ChartTypeTemplate() +{} + +// ____ XChartTypeTemplate ____ +uno::Reference< XDiagram > SAL_CALL ChartTypeTemplate::createDiagramByDataSource( + const uno::Reference< data::XDataSource >& xDataSource, + const uno::Sequence< beans::PropertyValue >& aArguments ) +{ + Reference< XDiagram > xDia; + + try + { + // create diagram + xDia.set( + GetComponentContext()->getServiceManager()->createInstanceWithContext( + "com.sun.star.chart2.Diagram", + GetComponentContext() ), + uno::UNO_QUERY_THROW ); + + // modify diagram + Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter()); + chart2::InterpretedData aData( + xInterpreter->interpretDataSource( + xDataSource, aArguments, Sequence< Reference< XDataSeries > >() )); + + const Sequence< Sequence< Reference< XDataSeries > > > aSeries( aData.Series ); + sal_Int32 nCount = 0; + for( auto const & i : aSeries ) + for( auto const & j : i ) + lcl_applyDefaultStyle( j, nCount++, xDia ); + + Sequence< Reference< XChartType > > aOldChartTypesSeq; + FillDiagram( xDia, aData.Series, aData.Categories, aOldChartTypesSeq ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xDia; +} + +sal_Bool SAL_CALL ChartTypeTemplate::supportsCategories() +{ + return true; +} + +void SAL_CALL ChartTypeTemplate::changeDiagram( const uno::Reference< XDiagram >& xDiagram ) +{ + if( ! xDiagram.is()) + return; + + try + { + Sequence< Sequence< Reference< XDataSeries > > > aSeriesSeq( + DiagramHelper::getDataSeriesGroups( xDiagram )); + Sequence< Reference< XDataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq )); + const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.getLength(); + + // chart-type specific interpretation of existing data series + Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter()); + chart2::InterpretedData aData; + aData.Series = aSeriesSeq; + aData.Categories = DiagramHelper::getCategoriesFromDiagram( xDiagram ); + + if( xInterpreter->isDataCompatible( aData ) ) + { + aData = xInterpreter->reinterpretDataSeries( aData ); + } + else + { + Reference< data::XDataSource > xSource( xInterpreter->mergeInterpretedData( aData )); + // todo: get a "range-union" from the data provider by calling + // OUString aRange = getRangeRepresentationByData( xSource ); + // xSource.set( getDataByRangeRepresentation( aRange, aParam )); + // where aParam == ?? + Sequence< beans::PropertyValue > aParam; + if( aData.Categories.is()) + { + aParam.realloc( 1 ); + aParam[0] = beans::PropertyValue( "HasCategories", -1, uno::Any( true ), + beans::PropertyState_DIRECT_VALUE ); + } + aData = xInterpreter->interpretDataSource( xSource, aParam, aFlatSeriesSeq ); + } + aSeriesSeq = aData.Series; + + sal_Int32 nIndex = 0; + for( auto const & i : std::as_const(aSeriesSeq) ) + for( auto const & j : i ) + { + if( nIndex >= nFormerSeriesCount ) + lcl_applyDefaultStyle( j, nIndex++, xDiagram ); + } + + // remove charttype groups from all coordinate systems + Sequence< Reference< XChartType > > aOldChartTypesSeq( + DiagramHelper::getChartTypesFromDiagram(xDiagram) ); + + Reference< XCoordinateSystemContainer > xCoordSysCnt( xDiagram, uno::UNO_QUERY ); + OSL_ASSERT( xCoordSysCnt.is()); + if( xCoordSysCnt.is()) + { + const Sequence< Reference< XCoordinateSystem > > aCooSysSeq( + xCoordSysCnt->getCoordinateSystems()); + for( Reference< XCoordinateSystem > const & coords : aCooSysSeq ) + { + Reference< XChartTypeContainer > xContainer( coords, uno::UNO_QUERY ); + if( xContainer.is() ) + xContainer->setChartTypes( Sequence< Reference< XChartType > >() ); + } + } + + FillDiagram( xDiagram, aSeriesSeq, aData.Categories, aOldChartTypesSeq ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void SAL_CALL ChartTypeTemplate::changeDiagramData( + const Reference< chart2::XDiagram >& xDiagram, + const Reference< chart2::data::XDataSource >& xDataSource, + const Sequence< beans::PropertyValue >& aArguments ) +{ + if( ! (xDiagram.is() && + xDataSource.is()) ) + return; + + try + { + // interpret new data and re-use existing series + Sequence< Reference< XDataSeries > > aFlatSeriesSeq( + comphelper::containerToSequence( DiagramHelper::getDataSeriesFromDiagram( xDiagram ))); + const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.getLength(); + Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter()); + chart2::InterpretedData aData = + xInterpreter->interpretDataSource( xDataSource, aArguments, aFlatSeriesSeq ); + + // data series + Sequence< Sequence< Reference< XDataSeries > > > aSeriesSeq( aData.Series ); + + sal_Int32 i, j, nIndex = 0; + for( i=0; i<aSeriesSeq.getLength(); ++i ) + for( j=0; j<aSeriesSeq[i].getLength(); ++j, ++nIndex ) + { + if( nIndex >= nFormerSeriesCount ) + { + lcl_applyDefaultStyle( aSeriesSeq[i][j], nIndex, xDiagram ); + applyStyle( aSeriesSeq[i][j], i, j, aSeriesSeq[i].getLength() ); + } + } + + // categories + DiagramHelper::setCategoriesToDiagram( aData.Categories, xDiagram, true, supportsCategories() ); + + Sequence< Reference< XChartType > > aChartTypes( + DiagramHelper::getChartTypesFromDiagram( xDiagram )); + sal_Int32 nMax = std::min( aChartTypes.getLength(), aSeriesSeq.getLength()); + for( i=0; i<nMax; ++i ) + { + Reference< XDataSeriesContainer > xDSCnt( aChartTypes[i], uno::UNO_QUERY_THROW ); + xDSCnt->setDataSeries( aSeriesSeq[i] ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +sal_Bool SAL_CALL ChartTypeTemplate::matchesTemplate( + const Reference< chart2::XDiagram >& xDiagram, + sal_Bool /* bAdaptProperties */ ) +{ + bool bResult = false; + + if( ! xDiagram.is()) + return bResult; + + try + { + Reference< XCoordinateSystemContainer > xCooSysCnt( + xDiagram, uno::UNO_QUERY_THROW ); + Sequence< Reference< XCoordinateSystem > > aCooSysSeq( + xCooSysCnt->getCoordinateSystems()); + + // need to have at least one coordinate system + bResult = aCooSysSeq.hasElements(); + if( bResult ) + { + Sequence< Reference< XChartType > > aFormerlyUsedChartTypes; + Reference<XChartType> xOldCT = getChartTypeForNewSeries(aFormerlyUsedChartTypes); + if (!xOldCT.is()) + return false; + + const OUString aChartTypeToMatch = xOldCT->getChartType(); + const sal_Int32 nDimensionToMatch = getDimension(); + for( sal_Int32 nCooSysIdx=0; bResult && (nCooSysIdx < aCooSysSeq.getLength()); ++nCooSysIdx ) + { + // match dimension + bResult = bResult && (aCooSysSeq[nCooSysIdx]->getDimension() == nDimensionToMatch); + + Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW ); + Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes()); + for( sal_Int32 nCTIdx=0; bResult && (nCTIdx < aChartTypeSeq.getLength()); ++nCTIdx ) + { + if (!aChartTypeSeq[nCTIdx].is()) + return false; + + // match chart type + bResult = bResult && aChartTypeSeq[nCTIdx]->getChartType() == aChartTypeToMatch; + bool bFound=false; + bool bAmbiguous=false; + // match stacking mode + bResult = bResult && + ( DiagramHelper::getStackModeFromChartType( + aChartTypeSeq[nCTIdx], bFound, bAmbiguous, + aCooSysSeq[nCooSysIdx] ) + == getStackMode( nCTIdx ) ); + } + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return bResult; +} + +Reference< chart2::XDataInterpreter > SAL_CALL ChartTypeTemplate::getDataInterpreter() +{ + if( ! m_xDataInterpreter.is()) + m_xDataInterpreter.set( new DataInterpreter ); + + return m_xDataInterpreter; +} + +void SAL_CALL ChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 /* nSeriesIndex */, + ::sal_Int32 /* nSeriesCount */ ) +{ + // sset stacking mode + Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY ); + if( !xSeriesProp.is()) + return; + + try + { + StackMode eStackMode = getStackMode( nChartTypeIndex ); + const uno::Any aPropValue( + ( (eStackMode == StackMode::YStacked) || + (eStackMode == StackMode::YStackedPercent) ) + ? chart2::StackingDirection_Y_STACKING + : (eStackMode == StackMode::ZStacked ) + ? chart2::StackingDirection_Z_STACKING + : chart2::StackingDirection_NO_STACKING ); + xSeriesProp->setPropertyValue( "StackingDirection", aPropValue ); + + //ensure valid label placement + { + uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements( + getChartTypeForIndex( nChartTypeIndex ), isSwapXAndY(), xSeries ) ); + lcl_ensureCorrectLabelPlacement( xSeriesProp, aAvailablePlacements ); + + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xSeriesProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList ) + for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) + lcl_ensureCorrectLabelPlacement( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]), aAvailablePlacements ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void ChartTypeTemplate::applyStyles( const Reference< chart2::XDiagram >& xDiagram ) +{ + // apply chart-type specific styles, like "symbols on" for example + Sequence< Sequence< Reference< XDataSeries > > > aNewSeriesSeq( + DiagramHelper::getDataSeriesGroups( xDiagram )); + for( sal_Int32 i=0; i<aNewSeriesSeq.getLength(); ++i ) + { + const sal_Int32 nNumSeries = aNewSeriesSeq[i].getLength(); + for( sal_Int32 j=0; j<nNumSeries; ++j ) + applyStyle( aNewSeriesSeq[i][j], i, j, nNumSeries ); + } + + //ensure valid empty cell handling (for first chart type...) + lcl_ensureCorrectMissingValueTreatment( xDiagram, getChartTypeForIndex( 0 ) ); +} + +void SAL_CALL ChartTypeTemplate::resetStyles( const Reference< chart2::XDiagram >& xDiagram ) +{ + // reset number format if we had percent stacking on + bool bPercent = (getStackMode(0) == StackMode::YStackedPercent); + if( bPercent ) + { + const Sequence< Reference< chart2::XAxis > > aAxisSeq( AxisHelper::getAllAxesOfDiagram( xDiagram ) ); + for( Reference< chart2::XAxis > const & axis : aAxisSeq ) + { + if( AxisHelper::getDimensionIndexOfAxis( axis, xDiagram )== 1 ) + { + Reference< beans::XPropertySet > xAxisProp( axis, uno::UNO_QUERY ); + if( xAxisProp.is()) + { + // set number format to source format + xAxisProp->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::Any(true)); + xAxisProp->setPropertyValue(CHART_UNONAME_NUMFMT, uno::Any()); + } + } + } + } + + //reset label placement if default + { + uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY ); + if( xCooSysContainer.is() ) + { + const uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() ); + for( uno::Reference< XCoordinateSystem > const & xCooSys : aCooSysList ) + { + //iterate through all chart types in the current coordinate system + uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY ); + OSL_ASSERT( xChartTypeContainer.is()); + if( !xChartTypeContainer.is() ) + continue; + const uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() ); + for( uno::Reference< XChartType > const & xChartType : aChartTypeList ) + { + //iterate through all series in this chart type + uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY ); + OSL_ASSERT( xDataSeriesContainer.is()); + if( !xDataSeriesContainer.is() ) + continue; + + const uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() ); + for( Reference< XDataSeries > const & xSeries : aSeriesList ) + { + Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY ); + if(!xSeries.is() || !xSeriesProp.is() ) + continue; + + uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements( + xChartType, isSwapXAndY(), xSeries ) ); + if(!aAvailablePlacements.hasElements()) + continue; + + sal_Int32 nDefaultPlacement = aAvailablePlacements[0]; + + lcl_resetLabelPlacementIfDefault( xSeriesProp, nDefaultPlacement ); + + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xSeriesProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList ) + for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) + lcl_resetLabelPlacementIfDefault( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]), nDefaultPlacement ); + } + } + } + } + } + +} + +// ____ XServiceName ____ + OUString SAL_CALL ChartTypeTemplate::getServiceName() +{ + return m_aServiceName; +} + +sal_Int32 ChartTypeTemplate::getDimension() const +{ + return 2; +} + +StackMode ChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + return StackMode::NONE; +} + +bool ChartTypeTemplate::isSwapXAndY() const +{ + return false; +} + +void ChartTypeTemplate::createCoordinateSystems( + const Reference< chart2::XCoordinateSystemContainer > & xOutCooSysCnt ) +{ + if( ! xOutCooSysCnt.is()) + return; + Sequence< Reference< XChartType > > aFormerlyUsedChartTypes; + Reference< XChartType > xChartType( getChartTypeForNewSeries(aFormerlyUsedChartTypes)); + if( ! xChartType.is()) + return; + Reference< XCoordinateSystem > xCooSys( xChartType->createCoordinateSystem( getDimension())); + if( ! xCooSys.is()) + { + // chart type wants no coordinate systems + xOutCooSysCnt->setCoordinateSystems( Sequence< Reference< XCoordinateSystem > >()); + return; + } + // #i69680# make grid of first y-axis visible (was in the CooSys CTOR before) + if( xCooSys->getDimension() >= 2 ) + { + Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1, 0 )); + if( xAxis.is()) + AxisHelper::makeGridVisible( xAxis->getGridProperties() ); + } + + Sequence< Reference< XCoordinateSystem > > aCoordinateSystems( + xOutCooSysCnt->getCoordinateSystems()); + + if( aCoordinateSystems.hasElements()) + { + bool bOk = true; + for( sal_Int32 i=0; bOk && i<aCoordinateSystems.getLength(); ++i ) + bOk = bOk && ( xCooSys->getCoordinateSystemType() == aCoordinateSystems[i]->getCoordinateSystemType() && + (xCooSys->getDimension() == aCoordinateSystems[i]->getDimension()) ); + // coordinate systems are ok + if( bOk ) + return; + // there are coordinate systems but they do not fit. So overwrite them. + } + + //copy as much info from former coordinate system as possible: + if( aCoordinateSystems.hasElements() ) + { + Reference< XCoordinateSystem > xOldCooSys( aCoordinateSystems[0] ); + sal_Int32 nMaxDimensionCount = std::min( xCooSys->getDimension(), xOldCooSys->getDimension() ); + + for(sal_Int32 nDimensionIndex=0; nDimensionIndex<nMaxDimensionCount; nDimensionIndex++) + { + const sal_Int32 nMaximumAxisIndex = xOldCooSys->getMaximumAxisIndexByDimension(nDimensionIndex); + for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex) + { + uno::Reference< XAxis > xAxis( xOldCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) ); + if( xAxis.is()) + { + xCooSys->setAxisByDimension( nDimensionIndex, xAxis, nAxisIndex ); + } + } + } + } + + // set new coordinate systems + aCoordinateSystems.realloc( 1 ); + aCoordinateSystems[0] = xCooSys; + + xOutCooSysCnt->setCoordinateSystems( aCoordinateSystems ); +} + +void ChartTypeTemplate::adaptScales( + const Sequence< Reference< chart2::XCoordinateSystem > > & aCooSysSeq, + const Reference< data::XLabeledDataSequence > & xCategories //@todo: in future there may be more than one sequence of categories (e.g. charttype with categories at x and y axis ) + ) +{ + bool bSupportsCategories( supportsCategories() ); + for( Reference< XCoordinateSystem > const & xCooSys : aCooSysSeq ) + { + try + { + if( !xCooSys.is() ) + continue; + + // attach categories to first axis + sal_Int32 nDim( xCooSys->getDimension()); + if( nDim > 0 ) + { + const sal_Int32 nDimensionX = 0; + const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionX); + for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI) + { + Reference< XAxis > xAxis( xCooSys->getAxisByDimension(nDimensionX,nI) ); + if( xAxis.is()) + { + ScaleData aData( xAxis->getScaleData() ); + aData.Categories = xCategories; + if(bSupportsCategories) + { + Reference< XChartType > xChartType(getChartTypeForNewSeries(Sequence< Reference< XChartType > >())); + if( aData.AxisType == AxisType::CATEGORY ) + { + aData.ShiftedCategoryPosition = m_aServiceName.indexOf("Column") != -1 || m_aServiceName.indexOf("Bar") != -1 || m_aServiceName.endsWith("Close"); + } + bool bSupportsDates = ::chart::ChartTypeHelper::isSupportingDateAxis( xChartType, nDimensionX ); + if( aData.AxisType != AxisType::CATEGORY && ( aData.AxisType != AxisType::DATE || !bSupportsDates) ) + { + aData.AxisType = AxisType::CATEGORY; + aData.AutoDateAxis = true; + AxisHelper::removeExplicitScaling( aData ); + } + } + else + aData.AxisType = AxisType::REALNUMBER; + + xAxis->setScaleData( aData ); + } + } + } + // set percent stacking mode at second axis + if( nDim > 1 ) + { + const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(1); + for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI) + { + Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1,nI )); + if( xAxis.is()) + { + bool bPercent = (getStackMode(0) == StackMode::YStackedPercent); + chart2::ScaleData aScaleData = xAxis->getScaleData(); + + if( bPercent != (aScaleData.AxisType==AxisType::PERCENT) ) + { + if( bPercent ) + aScaleData.AxisType = AxisType::PERCENT; + else + aScaleData.AxisType = AxisType::REALNUMBER; + xAxis->setScaleData( aScaleData ); + } + } + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } +} + +void ChartTypeTemplate::adaptDiagram( const Reference< XDiagram > & /* xDiagram */ ) +{ + } + +void ChartTypeTemplate::createAxes( + const Sequence< Reference< XCoordinateSystem > > & rCoordSys ) +{ + //create missing axes + if( !rCoordSys.hasElements() ) + return; + + Reference< XCoordinateSystem > xCooSys( rCoordSys[0] ); + if(!xCooSys.is()) + return; + + //create main axis in first coordinate system + sal_Int32 nDimCount = xCooSys->getDimension(); + sal_Int32 nDim=0; + for( nDim=0; nDim<nDimCount; ++nDim ) + { + sal_Int32 nAxisCount = getAxisCountByDimension( nDim ); + if( nDim == 1 && + nAxisCount < 2 && AxisHelper::isSecondaryYAxisNeeded( xCooSys )) + nAxisCount = 2; + for( sal_Int32 nAxisIndex = 0; nAxisIndex < nAxisCount; ++nAxisIndex ) + { + Reference< XAxis > xAxis = AxisHelper::getAxis( nDim, nAxisIndex, xCooSys ); + if( !xAxis.is()) + { + // create and add axis + xAxis.set( AxisHelper::createAxis( + nDim, nAxisIndex, xCooSys, GetComponentContext() )); + } + } + } +} + +void ChartTypeTemplate::adaptAxes( + const Sequence< Reference< XCoordinateSystem > > & rCoordSys ) +{ + //adapt properties of existing axes and remove superfluous axes + + if( !rCoordSys.hasElements() ) + return; + + for( Reference< XCoordinateSystem > const & xCooSys : rCoordSys ) + { + if( !xCooSys.is() ) + continue; + sal_Int32 nDimCount = xCooSys->getDimension(); + for( sal_Int32 nDim=0; nDim<nDimCount; ++nDim ) + { + sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension( nDim ); + for( sal_Int32 nAxisIndex=0; nAxisIndex<=nMaxAxisIndex; nAxisIndex++ ) + { + Reference< XAxis > xAxis( AxisHelper::getAxis( nDim, nAxisIndex, xCooSys ) ); + if( !xAxis.is() ) + continue; + + if( nAxisIndex == MAIN_AXIS_INDEX || nAxisIndex == SECONDARY_AXIS_INDEX ) + { + // adapt scales + bool bPercent = (getStackMode(0) == StackMode::YStackedPercent); + if( bPercent && nDim == 1 ) + { + Reference< beans::XPropertySet > xAxisProp( xAxis, uno::UNO_QUERY ); + if( xAxisProp.is()) + { + // set number format to source format + xAxisProp->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::Any(true)); + xAxisProp->setPropertyValue(CHART_UNONAME_NUMFMT, uno::Any()); + } + } + } + } + } + } +} + +sal_Int32 ChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension ) +{ + return (nDimension < getDimension()) ? 1 : 0; +} + +void ChartTypeTemplate::FillDiagram( + const Reference< XDiagram >& xDiagram, + const Sequence< Sequence< Reference< XDataSeries > > >& aSeriesSeq, + const Reference< data::XLabeledDataSequence >& xCategories, + const Sequence< Reference< XChartType > >& aOldChartTypesSeq ) +{ + adaptDiagram( xDiagram ); + + try + { + // create coordinate systems and scales + Reference< XCoordinateSystemContainer > xCoordSysCnt( xDiagram, uno::UNO_QUERY_THROW ); + createCoordinateSystems( xCoordSysCnt ); + Sequence< Reference< XCoordinateSystem > > aCoordinateSystems( xCoordSysCnt->getCoordinateSystems()); + createAxes( aCoordinateSystems ); + adaptAxes( aCoordinateSystems ); + adaptScales( aCoordinateSystems, xCategories ); + + // chart types + createChartTypes( aSeriesSeq, aCoordinateSystems, aOldChartTypesSeq ); + applyStyles( xDiagram ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void ChartTypeTemplate::createChartTypes( + const Sequence< Sequence< Reference< XDataSeries > > > & aSeriesSeq, + const Sequence< Reference< XCoordinateSystem > > & rCoordSys, + const Sequence< Reference< XChartType > >& aOldChartTypesSeq ) +{ + if( ! rCoordSys.hasElements() || + ! rCoordSys[0].is() ) + return; + + try + { + sal_Int32 nCooSysIdx=0; + Reference< XChartType > xCT; + if( !aSeriesSeq.hasElements() ) + { + // we need a new chart type + xCT.set( getChartTypeForNewSeries( aOldChartTypesSeq )); + Reference< XChartTypeContainer > xCTCnt( rCoordSys[nCooSysIdx], uno::UNO_QUERY_THROW ); + Sequence< Reference< XChartType > > aCTSeq( xCTCnt->getChartTypes()); + aCTSeq.realloc( 1 ); + aCTSeq[0] = xCT; + xCTCnt->setChartTypes( aCTSeq ); + } + else + { + for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx ) + { + if( nSeriesIdx == nCooSysIdx ) + { + // we need a new chart type + xCT.set( getChartTypeForNewSeries( aOldChartTypesSeq )); + Reference< XChartTypeContainer > xCTCnt( rCoordSys[nCooSysIdx], uno::UNO_QUERY_THROW ); + Sequence< Reference< XChartType > > aCTSeq( xCTCnt->getChartTypes()); + if( aCTSeq.hasElements()) + { + aCTSeq[0] = xCT; + xCTCnt->setChartTypes( aCTSeq ); + } + else + xCTCnt->addChartType( xCT ); + + Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + xDSCnt->setDataSeries( aSeriesSeq[nSeriesIdx] ); + } + else + { + // reuse existing chart type + OSL_ASSERT( xCT.is()); + Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + Sequence< Reference< XDataSeries > > aNewSeriesSeq( xDSCnt->getDataSeries()); + sal_Int32 nNewStartIndex = aNewSeriesSeq.getLength(); + aNewSeriesSeq.realloc( nNewStartIndex + aSeriesSeq[nSeriesIdx].getLength() ); + std::copy( aSeriesSeq[nSeriesIdx].begin(), + aSeriesSeq[nSeriesIdx].end(), + aNewSeriesSeq.getArray() + nNewStartIndex ); + xDSCnt->setDataSeries( aNewSeriesSeq ); + } + + // spread the series over the available coordinate systems + if( rCoordSys.getLength() > (nCooSysIdx + 1) ) + ++nCooSysIdx; + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( + const Sequence< Reference< XChartType > > & rOldChartTypesSeq, + const Reference< XChartType > & xNewChartType ) +{ + Reference< beans::XPropertySet > xDestination( xNewChartType, uno::UNO_QUERY ); + if( !xDestination.is() ) + return; + + OUString aNewChartType( xNewChartType->getChartType() ); + + Reference< beans::XPropertySet > xSource; + for( Reference< XChartType > const & xOldType : rOldChartTypesSeq ) + { + if( xOldType.is() && xOldType->getChartType() == aNewChartType ) + { + xSource.set( Reference< beans::XPropertySet >(xOldType, uno::UNO_QUERY ) ); + if( xSource.is() ) + break; + } + } + if( xSource.is() ) + comphelper::copyProperties( xSource, xDestination ); +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ChartTypeTemplate.hxx b/chart2/source/model/template/ChartTypeTemplate.hxx new file mode 100644 index 000000000..0fe236ce1 --- /dev/null +++ b/chart2/source/model/template/ChartTypeTemplate.hxx @@ -0,0 +1,256 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CHARTTYPETEMPLATE_HXX + +#include <cppuhelper/implbase.hxx> +#include <StackMode.hxx> +#include <com/sun/star/chart2/XChartTypeTemplate.hpp> +#include <com/sun/star/lang/XServiceName.hpp> + +namespace com::sun::star::chart2 { class XChartType; } +namespace com::sun::star::chart2 { class XCoordinateSystemContainer; } +namespace com::sun::star::chart2 { class XDataSeries; } +namespace com::sun::star::uno { class XComponentContext; } + +namespace chart +{ + +/** For creating diagrams and modifying existing diagrams. A base class that + implements XChartTypeTemplate and offers some tooling for classes that + derive from this class. + + createDiagramByDataSource + + This does the following steps using some virtual helper-methods, that may be + overridden by derived classes: + + * creates an XDiagram via service-factory. + + * convert the given XDataSource to a sequence of XDataSeries using the + method createDataSeries(). In this class the DataInterpreter helper class + is used to create a standard interpretation (just y-values). + + * call applyDefaultStyle() for all XDataSeries in order to apply default + styles. In this class the series get the system-wide default colors as + "Color" property. + + * call applyStyle() for applying chart-type specific styles to all series. + The default implementation is empty. + + * call createCoordinateSystems() and apply them to the diagram. As + default one cartesian system with Scales using a linear Scaling is + created. + + * createChartTypes() is called in order to define the structure of the + diagram. For details see comment of this function. As default this + method creates a tree where all series appear in one branch with the chart + type determined by getChartTypeForNewSeries(). The stacking is determined + via the method getStackMode(). + + * create an XLegend via the global service factory, set it at the diagram. + */ +class ChartTypeTemplate : public ::cppu::WeakImplHelper< + css::chart2::XChartTypeTemplate, + css::lang::XServiceName > +{ +public: + explicit ChartTypeTemplate( css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName ); + virtual ~ChartTypeTemplate() override; + +protected: + // ____ XChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XDiagram > SAL_CALL createDiagramByDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xDataSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments ) override; + /// denotes if the chart needs categories at the first scale + virtual sal_Bool SAL_CALL supportsCategories() override; + + virtual void SAL_CALL changeDiagram( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) override; + virtual void SAL_CALL changeDiagramData( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + const css::uno::Reference< css::chart2::data::XDataSource >& xDataSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments ) override; + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< + css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + // still abstract: getChartTypeForNewSeries() + virtual css::uno::Reference< css::chart2::XDataInterpreter > SAL_CALL getDataInterpreter() override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void SAL_CALL resetStyles( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) override; + + /// @throws css::uno::RuntimeException + void applyStyles( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ); + + // ____ XServiceName ____ + virtual OUString SAL_CALL getServiceName() override; + + // Methods to override for automatic creation + + /// returns 2 by default. Supported are 2 and 3 + virtual sal_Int32 getDimension() const; + + /** returns StackMode::NONE by default. This is a global flag used for all + series of a specific chart type. If percent stacking is supported, the + percent stacking mode is retrieved from the first chart type (index 0) + + @param nChartTypeIndex denotes the index of the charttype in means + defined by the template creation order, i.e., 0 means the first + chart type that a template creates. + */ + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const; + + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) = 0; + + virtual bool isSwapXAndY() const; + + // Methods for creating the diagram piecewise + + /** Allows derived classes to manipulate the diagrams whole, like changing + the wall color. The default implementation is empty. It is called by + FillDiagram which is called by createDiagramByDataSource and + changeDiagram + */ + virtual void adaptDiagram( + const css::uno::Reference< css::chart2::XDiagram > & xDiagram ); + + /** Creates a 2d or 3d cartesian coordinate system with mathematically + oriented, linear scales with auto-min/max. If the given + CoordinateSystemContainer is not empty, those coordinate system should + be reused. + + <p>The dimension depends on the value returned by getDimension().</p> + */ + virtual void createCoordinateSystems( + const css::uno::Reference< css::chart2::XCoordinateSystemContainer > & xOutCooSysCnt ); + + /** Sets categories at the scales of dimension 0 and the percent stacking at + the scales of dimension 1 of all given coordinate systems. + + <p>Called by FillDiagram.</p> + */ + virtual void adaptScales( + const css::uno::Sequence< css::uno::Reference< css::chart2::XCoordinateSystem > > & aCooSysSeq, + const css::uno::Reference< css::chart2::data::XLabeledDataSequence > & xCategories ); + + /** create a data series tree, that fits the requirements of the chart type. + + <p>As default, this creates a tree with the following structure:</p> + + <pre> + root + | + +-- chart type (determined by getChartTypeForNewSeries()) + | + +-- category (DiscreteStackableScaleGroup using scale 0) + | + +-- values (ContinuousStackableScaleGroup using scale 1) + | + +-- series 0 + | + +-- series 1 + | + ... + | + +.. series n-1 + </pre> + + <p>If there are less than two scales available the returned tree is + empty.</p> + */ + virtual void createChartTypes( + const css::uno::Sequence< + css::uno::Sequence< + css::uno::Reference< + css::chart2::XDataSeries > > > & aSeriesSeq, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XCoordinateSystem > > & rCoordSys, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XChartType > > & aOldChartTypesSeq + ); + + /** create axes and add them to the given container. If there are already + compatible axes in the container these should be maintained. + + <p>As default, this method creates as many axes as there are dimensions + in the given first coordinate system. Each of the axis + represents one of the dimensions of the coordinate systems. If there are series + requesting a secondary axes a secondary y axes is added</p> + */ + void createAxes( + const css::uno::Sequence< css::uno::Reference< css::chart2::XCoordinateSystem > > & rCoordSys ); + + /** Give the number of requested axis per dimension here. Default is one + axis for each dimension + */ + virtual sal_Int32 getAxisCountByDimension( sal_Int32 nDimension ); + + /** adapt properties of existing axes and remove superfluous axes + */ + virtual void adaptAxes( + const css::uno::Sequence< css::uno::Reference< css::chart2::XCoordinateSystem > > & rCoordSys ); + + const css::uno::Reference< css::uno::XComponentContext >& + GetComponentContext() const { return m_xContext;} + + static void copyPropertiesFromOldToNewCoordinateSystem( + const css::uno::Sequence< css::uno::Reference< css::chart2::XChartType > > & rOldChartTypesSeq, + const css::uno::Reference< css::chart2::XChartType > & xNewChartType ); + +protected: + css::uno::Reference< css::uno::XComponentContext > m_xContext; + mutable css::uno::Reference< css::chart2::XDataInterpreter > m_xDataInterpreter; + +private: + const OUString m_aServiceName; + +private: + /** modifies the given diagram + */ + void FillDiagram( const css::uno::Reference< + css::chart2::XDiagram > & xDiagram, + const css::uno::Sequence< + css::uno::Sequence< + css::uno::Reference< + css::chart2::XDataSeries > > > & aSeriesSeq, + const css::uno::Reference< + css::chart2::data::XLabeledDataSequence >& xCategories, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XChartType > > & aOldChartTypesSeq); +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_CHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ColumnChartType.cxx b/chart2/source/model/template/ColumnChartType.cxx new file mode 100644 index 000000000..4c95b1c1b --- /dev/null +++ b/chart2/source/model/template/ColumnChartType.cxx @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ColumnChartType.hxx" +#include <servicenames_charttypes.hxx> +#include <PropertyHelper.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <cppuhelper/supportsservice.hxx> + +namespace com::sun::star::uno { class XComponentContext; } + +using namespace ::com::sun::star; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::Property; + +namespace +{ + +enum +{ + PROP_BARCHARTTYPE_OVERLAP_SEQUENCE, + PROP_BARCHARTTYPE_GAPWIDTH_SEQUENCE +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "OverlapSequence", + PROP_BARCHARTTYPE_OVERLAP_SEQUENCE, + cppu::UnoType<Sequence< sal_Int32 >>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + + rOutProperties.emplace_back( "GapwidthSequence", + PROP_BARCHARTTYPE_GAPWIDTH_SEQUENCE, + cppu::UnoType<Sequence< sal_Int32 >>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticColumnChartTypeDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + Sequence< sal_Int32 > aSeq(2); + + aSeq[0] = aSeq[1] = 0; + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_BARCHARTTYPE_OVERLAP_SEQUENCE, aSeq ); + + aSeq[0] = aSeq[1] = 100; + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_BARCHARTTYPE_GAPWIDTH_SEQUENCE, aSeq ); + } +}; + +struct StaticColumnChartTypeDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticColumnChartTypeDefaults_Initializer > +{ +}; + +struct StaticColumnChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticColumnChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticColumnChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticColumnChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticColumnChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticColumnChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticColumnChartTypeInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +ColumnChartType::ColumnChartType() +{} + +ColumnChartType::ColumnChartType( const ColumnChartType & rOther ) : + ChartType( rOther ) +{ +} + +ColumnChartType::~ColumnChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL ColumnChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new ColumnChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL ColumnChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_COLUMN; +} + +uno::Sequence< OUString > ColumnChartType::getSupportedPropertyRoles() +{ + uno::Sequence< OUString > aPropRoles(2); + aPropRoles[0] = "FillColor"; + aPropRoles[1] = "BorderColor"; + + return aPropRoles; +} + +// ____ OPropertySet ____ +uno::Any ColumnChartType::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticColumnChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL ColumnChartType::getInfoHelper() +{ + return *StaticColumnChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ColumnChartType::getPropertySetInfo() +{ + return *StaticColumnChartTypeInfo::get(); +} + +OUString SAL_CALL ColumnChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.ColumnChartType"; +} + +sal_Bool SAL_CALL ColumnChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL ColumnChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_COLUMN, + "com.sun.star.chart2.ChartType" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_ColumnChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::ColumnChartType()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ColumnChartType.hxx b/chart2/source/model/template/ColumnChartType.hxx new file mode 100644 index 000000000..d7b879479 --- /dev/null +++ b/chart2/source/model/template/ColumnChartType.hxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNCHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNCHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class ColumnChartType final : public ChartType +{ +public: + explicit ColumnChartType(); + virtual ~ColumnChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit ColumnChartType( const ColumnChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedPropertyRoles() override; + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNCHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx b/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx new file mode 100644 index 000000000..560332b81 --- /dev/null +++ b/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx @@ -0,0 +1,410 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ColumnLineChartTypeTemplate.hxx" +#include <CommonConverters.hxx> +#include <DiagramHelper.hxx> +#include <DataSeriesHelper.hxx> +#include <servicenames_charttypes.hxx> +#include "ColumnLineDataInterpreter.hxx" +#include <PropertyHelper.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/chart2/XChartTypeContainer.hpp> +#include <com/sun/star/chart2/XDataSeriesContainer.hpp> +#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +#include <algorithm> + +using namespace ::com::sun::star::chart2; +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::Property; + +namespace +{ + +enum +{ + PROP_COL_LINE_NUMBER_OF_LINES +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "NumberOfLines", + PROP_COL_LINE_NUMBER_OF_LINES, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticColumnLineChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aStaticDefaults, PROP_COL_LINE_NUMBER_OF_LINES, 1 ); + return &aStaticDefaults; + } +}; + +struct StaticColumnLineChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticColumnLineChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticColumnLineChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static uno::Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticColumnLineChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticColumnLineChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticColumnLineChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticColumnLineChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticColumnLineChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticColumnLineChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +ColumnLineChartTypeTemplate::ColumnLineChartTypeTemplate( + Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + sal_Int32 nNumberOfLines ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ), + m_eStackMode( eStackMode ) +{ + setFastPropertyValue_NoBroadcast( PROP_COL_LINE_NUMBER_OF_LINES, uno::Any( nNumberOfLines )); +} + +ColumnLineChartTypeTemplate::~ColumnLineChartTypeTemplate() +{} + +// ____ OPropertySet ____ +uno::Any ColumnLineChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticColumnLineChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL ColumnLineChartTypeTemplate::getInfoHelper() +{ + return *StaticColumnLineChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ColumnLineChartTypeTemplate::getPropertySetInfo() +{ + return *StaticColumnLineChartTypeTemplateInfo::get(); +} + +void ColumnLineChartTypeTemplate::createChartTypes( + const Sequence< Sequence< Reference< XDataSeries > > > & aSeriesSeq, + const Sequence< Reference< XCoordinateSystem > > & rCoordSys, + const Sequence< Reference< XChartType > >& aOldChartTypesSeq ) +{ + if( ! rCoordSys.hasElements() || + ! rCoordSys[0].is() ) + return; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + Sequence< Reference< XDataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq )); + sal_Int32 nNumberOfSeries = aFlatSeriesSeq.getLength(); + sal_Int32 nNumberOfLines = 0; + sal_Int32 nNumberOfColumns = 0; + + getFastPropertyValue( PROP_COL_LINE_NUMBER_OF_LINES ) >>= nNumberOfLines; + OSL_ENSURE( nNumberOfLines>=0, "number of lines should be not negative" ); + if( nNumberOfLines < 0 ) + nNumberOfLines = 0; + + if( nNumberOfLines >= nNumberOfSeries ) + { + if( nNumberOfSeries > 0 ) + { + nNumberOfLines = nNumberOfSeries - 1; + nNumberOfColumns = 1; + } + else + nNumberOfLines = 0; + } + else + nNumberOfColumns = nNumberOfSeries - nNumberOfLines; + + // Columns + + Reference< XChartType > xCT( + xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ), uno::UNO_QUERY_THROW ); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aOldChartTypesSeq, xCT ); + + Reference< XChartTypeContainer > xCTCnt( rCoordSys[ 0 ], uno::UNO_QUERY_THROW ); + xCTCnt->setChartTypes( Sequence< Reference< chart2::XChartType > >( &xCT, 1 )); + + if( nNumberOfColumns > 0 ) + { + Reference< XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + Sequence< Reference< XDataSeries > > aColumnSeq( nNumberOfColumns ); + std::copy( aFlatSeriesSeq.begin(), + aFlatSeriesSeq.begin() + nNumberOfColumns, + aColumnSeq.getArray()); + xDSCnt->setDataSeries( aColumnSeq ); + } + + // Lines + + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW ); + xCTCnt.set( rCoordSys[ 0 ], uno::UNO_QUERY_THROW ); + xCTCnt->addChartType( xCT ); + + if( nNumberOfLines > 0 ) + { + Reference< XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + Sequence< Reference< XDataSeries > > aLineSeq( nNumberOfLines ); + std::copy( aFlatSeriesSeq.begin() + nNumberOfColumns, + aFlatSeriesSeq.end(), + aLineSeq.getArray()); + xDSCnt->setDataSeries( aLineSeq ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void SAL_CALL ColumnLineChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + if( nChartTypeIndex==0 ) // columns + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); + } + else if( nChartTypeIndex==1 ) // lines + { + Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY ); + if( xProp.is() ) + { + DataSeriesHelper::switchLinesOnOrOff( xProp, true ); + DataSeriesHelper::switchSymbolsOnOrOff( xProp, false, nSeriesIndex ); + DataSeriesHelper::makeLinesThickOrThin( xProp, true ); + } + } +} + +StackMode ColumnLineChartTypeTemplate::getStackMode( sal_Int32 nChartTypeIndex ) const +{ + if( nChartTypeIndex == 0 ) + return m_eStackMode; + return StackMode::NONE; +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL ColumnLineChartTypeTemplate::matchesTemplate( + const uno::Reference< XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) +{ + bool bResult = false; + + if( ! xDiagram.is()) + return bResult; + + try + { + Reference< chart2::XChartType > xColumnChartType; + Reference< XCoordinateSystem > xColumnChartCooSys; + Reference< chart2::XChartType > xLineChartType; + sal_Int32 nNumberOfChartTypes = 0; + + Reference< XCoordinateSystemContainer > xCooSysCnt( + xDiagram, uno::UNO_QUERY_THROW ); + const Sequence< Reference< XCoordinateSystem > > aCooSysSeq( + xCooSysCnt->getCoordinateSystems()); + for( Reference< XCoordinateSystem > const & coords : aCooSysSeq ) + { + Reference< XChartTypeContainer > xCTCnt( coords, uno::UNO_QUERY_THROW ); + const Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes()); + for( Reference< XChartType > const & chartType : aChartTypeSeq ) + { + if( chartType.is()) + { + ++nNumberOfChartTypes; + if( nNumberOfChartTypes > 2 ) + break; + OUString aCTService = chartType->getChartType(); + if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ) + { + xColumnChartType.set( chartType ); + xColumnChartCooSys.set( coords ); + } + else if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_LINE ) + xLineChartType.set( chartType ); + } + } + if( nNumberOfChartTypes > 2 ) + break; + } + + if( nNumberOfChartTypes == 2 && + xColumnChartType.is() && + xLineChartType.is()) + { + OSL_ASSERT( xColumnChartCooSys.is()); + + // check stackmode of bars + bResult = (xColumnChartCooSys->getDimension() == getDimension()); + if( bResult ) + { + bool bFound=false; + bool bAmbiguous=false; + bResult = ( DiagramHelper::getStackModeFromChartType( + xColumnChartType, bFound, bAmbiguous, + xColumnChartCooSys ) + == getStackMode( 0 ) ); + + if( bResult && bAdaptProperties ) + { + Reference< XDataSeriesContainer > xSeriesContainer( xLineChartType, uno::UNO_QUERY ); + if( xSeriesContainer.is() ) + { + sal_Int32 nNumberOfLines = xSeriesContainer->getDataSeries().getLength(); + setFastPropertyValue_NoBroadcast( PROP_COL_LINE_NUMBER_OF_LINES, uno::Any( nNumberOfLines )); + } + } + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return bResult; +} + +Reference< chart2::XChartType > ColumnLineChartTypeTemplate::getChartTypeForIndex( sal_Int32 nChartTypeIndex ) +{ + Reference< chart2::XChartType > xCT; + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY ); + if(xFact.is()) + { + if( nChartTypeIndex == 0 ) + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ), uno::UNO_QUERY ); + else + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY ); + } + return xCT; +} + +Reference< XChartType > SAL_CALL ColumnLineChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW ); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< XDataInterpreter > SAL_CALL ColumnLineChartTypeTemplate::getDataInterpreter() +{ + if( ! m_xDataInterpreter.is()) + { + sal_Int32 nNumberOfLines = 1; + getFastPropertyValue( PROP_COL_LINE_NUMBER_OF_LINES ) >>= nNumberOfLines; + m_xDataInterpreter.set( new ColumnLineDataInterpreter( nNumberOfLines ) ); + } + else + { + //todo... + OSL_FAIL( "number of lines may not be valid anymore in the datainterpreter" ); + + } + + return m_xDataInterpreter; +} + +IMPLEMENT_FORWARD_XINTERFACE2( ColumnLineChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( ColumnLineChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ColumnLineChartTypeTemplate.hxx b/chart2/source/model/template/ColumnLineChartTypeTemplate.hxx new file mode 100644 index 000000000..9f04b633d --- /dev/null +++ b/chart2/source/model/template/ColumnLineChartTypeTemplate.hxx @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNLINECHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNLINECHARTTYPETEMPLATE_HXX + +#include "ChartTypeTemplate.hxx" +#include <StackMode.hxx> + +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class ColumnLineChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + explicit ColumnLineChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + sal_Int32 nNumberOfLines ); + virtual ~ColumnLineChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< + css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual css::uno::Reference< css::chart2::XDataInterpreter > SAL_CALL getDataInterpreter() override; + + // ____ ChartTypeTemplate ____ + virtual void createChartTypes( + const css::uno::Sequence< + css::uno::Sequence< + css::uno::Reference< + css::chart2::XDataSeries > > > & aSeriesSeq, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XCoordinateSystem > > & rCoordSys, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XChartType > > & aOldChartTypesSeq + ) override; + + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; + +private: + StackMode m_eStackMode; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNLINECHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ColumnLineDataInterpreter.cxx b/chart2/source/model/template/ColumnLineDataInterpreter.cxx new file mode 100644 index 000000000..b99324d27 --- /dev/null +++ b/chart2/source/model/template/ColumnLineDataInterpreter.cxx @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ColumnLineDataInterpreter.hxx" +#include <osl/diagnose.h> + +#include <algorithm> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using namespace ::std; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +namespace chart +{ + +// explicit +ColumnLineDataInterpreter::ColumnLineDataInterpreter( + sal_Int32 nNumberOfLines ) : + DataInterpreter(), + m_nNumberOfLines( nNumberOfLines ) +{} + +ColumnLineDataInterpreter::~ColumnLineDataInterpreter() +{} + +// ____ XDataInterpreter ____ +InterpretedData SAL_CALL ColumnLineDataInterpreter::interpretDataSource( + const Reference< data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const Sequence< Reference< XDataSeries > >& aSeriesToReUse ) +{ + InterpretedData aResult( DataInterpreter::interpretDataSource( xSource, aArguments, aSeriesToReUse )); + + // the base class should return one group + OSL_ASSERT( aResult.Series.getLength() == 1 ); + if( aResult.Series.getLength() == 1 ) + { + sal_Int32 nNumberOfSeries = aResult.Series[0].getLength(); + + // if we have more than one series put the last nNumOfLines ones into a new group + if( nNumberOfSeries > 1 && m_nNumberOfLines > 0 ) + { + sal_Int32 nNumOfLines = std::min( m_nNumberOfLines, nNumberOfSeries - 1 ); + aResult.Series.realloc(2); + + Sequence< Reference< XDataSeries > > & rColumnDataSeries = aResult.Series[0]; + Sequence< Reference< XDataSeries > > & rLineDataSeries = aResult.Series[1]; + rLineDataSeries.realloc( nNumOfLines ); + std::copy( rColumnDataSeries.begin() + nNumberOfSeries - nNumOfLines, + rColumnDataSeries.begin() + nNumberOfSeries, + rLineDataSeries.getArray() ); + rColumnDataSeries.realloc( nNumberOfSeries - nNumOfLines ); + } + } + + return aResult; +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ColumnLineDataInterpreter.hxx b/chart2/source/model/template/ColumnLineDataInterpreter.hxx new file mode 100644 index 000000000..e6956db4c --- /dev/null +++ b/chart2/source/model/template/ColumnLineDataInterpreter.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNLINEDATAINTERPRETER_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNLINEDATAINTERPRETER_HXX + +#include "DataInterpreter.hxx" + +namespace chart +{ + +class ColumnLineDataInterpreter : public DataInterpreter +{ +public: + explicit ColumnLineDataInterpreter( + sal_Int32 nNumberOfLines ); + virtual ~ColumnLineDataInterpreter() override; + +protected: + // ____ XDataInterpreter ____ + virtual css::chart2::InterpretedData SAL_CALL interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const css::uno::Sequence< css::uno::Reference< css::chart2::XDataSeries > >& aSeriesToReUse ) override; + +private: + sal_Int32 m_nNumberOfLines; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_COLUMNLINEDATAINTERPRETER_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/DataInterpreter.cxx b/chart2/source/model/template/DataInterpreter.cxx new file mode 100644 index 000000000..7e85e0b36 --- /dev/null +++ b/chart2/source/model/template/DataInterpreter.cxx @@ -0,0 +1,441 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "DataInterpreter.hxx" +#include <DataSeries.hxx> +#include <DataSourceHelper.hxx> +#include <DataSeriesHelper.hxx> +#include <CommonConverters.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/chart2/data/XDataSink.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <tools/diagnose_ex.h> + +#include <vector> +#include <algorithm> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using namespace ::std; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +#ifdef DEBUG_CHART2_TEMPLATE +namespace +{ +void lcl_ShowDataSource( const Reference< data::XDataSource > & xSource ); +} +#endif + +namespace chart +{ + +DataInterpreter::DataInterpreter() +{} + +DataInterpreter::~DataInterpreter() +{} + +// ____ XDataInterpreter ____ +InterpretedData SAL_CALL DataInterpreter::interpretDataSource( + const Reference< data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const Sequence< Reference< XDataSeries > >& aSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + +#ifdef DEBUG_CHART2_TEMPLATE + lcl_ShowDataSource( xSource ); +#endif + + const Sequence< Reference< data::XLabeledDataSequence > > aData( xSource->getDataSequences() ); + + Reference< data::XLabeledDataSequence > xCategories; + vector< Reference< data::XLabeledDataSequence > > aSequencesVec; + + // check if we should use categories + + bool bHasCategories( HasCategories( aArguments, aData )); + + // parse data + bool bCategoriesUsed = false; + for( Reference< data::XLabeledDataSequence > const & labeledData : aData ) + { + try + { + if( bHasCategories && ! bCategoriesUsed ) + { + xCategories.set( labeledData ); + if( xCategories.is()) + SetRole( xCategories->getValues(), "categories"); + bCategoriesUsed = true; + } + else + { + aSequencesVec.push_back( labeledData ); + if( labeledData.is()) + SetRole( labeledData->getValues(), "values-y"); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + // create DataSeries + sal_Int32 nSeriesIndex = 0; + vector< Reference< XDataSeries > > aSeriesVec; + aSeriesVec.reserve( aSequencesVec.size()); + + for (auto const& elem : aSequencesVec) + { + Sequence< Reference< data::XLabeledDataSequence > > aNewData( &elem, 1 ); + Reference< XDataSeries > xSeries; + if( nSeriesIndex < aSeriesToReUse.getLength()) + xSeries.set( aSeriesToReUse[nSeriesIndex] ); + else + xSeries.set( new DataSeries ); + OSL_ASSERT( xSeries.is() ); + Reference< data::XDataSink > xSink( xSeries, uno::UNO_QUERY ); + OSL_ASSERT( xSink.is() ); + xSink->setData( aNewData ); + + aSeriesVec.push_back( xSeries ); + ++nSeriesIndex; + } + + Sequence< Sequence< Reference< XDataSeries > > > aSeries(1); + aSeries[0] = comphelper::containerToSequence( aSeriesVec ); + return InterpretedData( aSeries, xCategories ); +} + +InterpretedData SAL_CALL DataInterpreter::reinterpretDataSeries( + const InterpretedData& aInterpretedData ) +{ + InterpretedData aResult( aInterpretedData ); + + sal_Int32 i=0; + Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + const sal_Int32 nCount = aSeries.getLength(); + for( ; i<nCount; ++i ) + { + try + { + Reference< data::XDataSource > xSeriesSource( aSeries[i], uno::UNO_QUERY_THROW ); + Sequence< Reference< data::XLabeledDataSequence > > aNewSequences; + + // values-y + Reference< data::XLabeledDataSequence > xValuesY( + DataSeriesHelper::getDataSequenceByRole( xSeriesSource, "values-y" )); + // re-use values-... as values-y + if( ! xValuesY.is()) + { + xValuesY.set( + DataSeriesHelper::getDataSequenceByRole( xSeriesSource, "values", true )); + if( xValuesY.is()) + SetRole( xValuesY->getValues(), "values-y"); + } + if( xValuesY.is()) + { + aNewSequences.realloc(1); + aNewSequences[0] = xValuesY; + } + + Sequence< Reference< data::XLabeledDataSequence > > aSeqs( xSeriesSource->getDataSequences()); + if( aSeqs.getLength() != aNewSequences.getLength() ) + { +#ifdef DEBUG_CHART2_TEMPLATE + sal_Int32 j=0; + for( ; j<aSeqs.(); ++j ) + { + assert( aSeqs[j] == xValuesY && "All sequences should be used" ); + } +#endif + Reference< data::XDataSink > xSink( xSeriesSource, uno::UNO_QUERY_THROW ); + xSink->setData( aNewSequences ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return aResult; +} + +// criterion: all series must have exactly one data::XLabeledDataSequence +sal_Bool SAL_CALL DataInterpreter::isDataCompatible( + const chart2::InterpretedData& aInterpretedData ) +{ + const Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + for( Reference< XDataSeries > const & i : aSeries ) + { + try + { + Reference< data::XDataSource > xSrc( i, uno::UNO_QUERY_THROW ); + Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSrc->getDataSequences()); + if( aSeq.getLength() != 1 ) + return false; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return true; +} + +namespace +{ + +struct lcl_LabeledSequenceEquals +{ + explicit lcl_LabeledSequenceEquals( const Reference< data::XLabeledDataSequence > & xLSeqToCmp ) : + m_bHasLabels ( false ), + m_bHasValues ( false ) + { + if( !xLSeqToCmp.is()) + return; + + Reference< data::XDataSequence > xSeq( xLSeqToCmp->getValues()); + if( xSeq.is()) + { + m_bHasValues = true; + m_aValuesRangeRep = xSeq->getSourceRangeRepresentation(); + } + + xSeq.set( xLSeqToCmp->getLabel()); + if( xSeq.is()) + { + m_bHasLabels = true; + m_aLabelRangeRep = xSeq->getSourceRangeRepresentation(); + } + } + + bool operator() ( const Reference< data::XLabeledDataSequence > & xSeq ) + { + if( ! xSeq.is()) + return false; + + Reference< data::XDataSequence > xSeqValues( xSeq->getValues() ); + Reference< data::XDataSequence > xSeqLabels( xSeq->getLabel() ); + bool bHasValues = xSeqValues.is(); + bool bHasLabels = xSeqLabels.is(); + + return ( ( (m_bHasValues == bHasValues) && + (!bHasValues || m_aValuesRangeRep == xSeqValues->getSourceRangeRepresentation()) ) && + ( (m_bHasLabels == bHasLabels) && + (!bHasLabels || m_aLabelRangeRep == xSeqLabels->getSourceRangeRepresentation()) ) + ); + } + +private: + bool m_bHasLabels; + bool m_bHasValues; + OUString m_aValuesRangeRep; + OUString m_aLabelRangeRep; +}; + +} // anonymous namespace + +Reference< data::XDataSource > SAL_CALL DataInterpreter::mergeInterpretedData( + const InterpretedData& aInterpretedData ) +{ + vector< Reference< data::XLabeledDataSequence > > aResultVec; + aResultVec.reserve( aInterpretedData.Series.getLength() + + 1 // categories + ); + + if( aInterpretedData.Categories.is()) + aResultVec.push_back( aInterpretedData.Categories ); + + const Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + for( Reference< XDataSeries > const & dataSeries : aSeries ) + { + try + { + Reference< data::XDataSource > xSrc( dataSeries, uno::UNO_QUERY_THROW ); + const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSrc->getDataSequences()); + + // add all sequences of data series + for( Reference< data::XLabeledDataSequence > const & xAdd : aSeq ) + { + // only add if sequence is not yet in the result + if( none_of( aResultVec.begin(), aResultVec.end(), + lcl_LabeledSequenceEquals( xAdd )) ) + { + aResultVec.push_back( xAdd ); + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return DataSourceHelper::createDataSource( comphelper::containerToSequence( aResultVec ) ); +} + +// convenience methods + +OUString DataInterpreter::GetRole( const Reference< data::XDataSequence > & xSeq ) +{ + OUString aResult; + if( ! xSeq.is()) + return aResult; + + try + { + Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW ); + xProp->getPropertyValue( "Role") >>= aResult; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + return aResult; +} + +void DataInterpreter::SetRole( const Reference< data::XDataSequence > & xSeq, const OUString & rRole ) +{ + if( ! xSeq.is()) + return; + try + { + Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW ); + xProp->setPropertyValue( "Role", uno::Any( rRole )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +uno::Any DataInterpreter::GetProperty( + const Sequence< beans::PropertyValue > & aArguments, + const OUString & rName ) +{ + for( sal_Int32 i=aArguments.getLength(); i--; ) + { + if( aArguments[i].Name == rName ) + return aArguments[i].Value; + } + return uno::Any(); +} + +bool DataInterpreter::HasCategories( + const Sequence< beans::PropertyValue > & rArguments, + const Sequence< Reference< data::XLabeledDataSequence > > & rData ) +{ + bool bHasCategories = false; + + if( rArguments.hasElements() ) + GetProperty( rArguments, "HasCategories" ) >>= bHasCategories; + + for( sal_Int32 nLSeqIdx=0; ! bHasCategories && nLSeqIdx<rData.getLength(); ++nLSeqIdx ) + bHasCategories = ( rData[nLSeqIdx].is() && GetRole( rData[nLSeqIdx]->getValues() ) == "categories"); + + return bHasCategories; +} + +bool DataInterpreter::UseCategoriesAsX( const Sequence< beans::PropertyValue > & rArguments ) +{ + bool bUseCategoriesAsX = true; + if( rArguments.hasElements() ) + GetProperty( rArguments, "UseCategoriesAsX" ) >>= bUseCategoriesAsX; + return bUseCategoriesAsX; +} + +OUString SAL_CALL DataInterpreter::getImplementationName() +{ + return "com.sun.star.comp.chart2.DataInterpreter"; +} + +sal_Bool SAL_CALL DataInterpreter::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL DataInterpreter::getSupportedServiceNames() +{ + return { "com.sun.star.chart2.DataInterpreter" }; +} + +} // namespace chart + +#ifdef DEBUG_CHART2_TEMPLATE +namespace +{ + +void lcl_ShowDataSource( const Reference< data::XDataSource > & xSource ) +{ + if( ! xSource.is()) + return; + + SAL_INFO("chart2", "DataSource in DataInterpreter:" ); + Sequence< Reference< data::XLabeledDataSequence > > aSequences( xSource->getDataSequences()); + Reference< beans::XPropertySet > xProp; + OUString aId; + const sal_Int32 nMax = aSequences.getLength(); + for( sal_Int32 k = 0; k < nMax; ++k ) + { + if( aSequences[k].is()) + { + OUString aSourceRepr("<none>"); + if( aSequences[k]->getValues().is()) + aSourceRepr = aSequences[k]->getValues()->getSourceRangeRepresentation(); + xProp.set( aSequences[k]->getValues(), uno::UNO_QUERY ); + if( xProp.is() && + ( xProp->getPropertyValue( "Role") >>= aId )) + { + SAL_INFO("chart2", " <data sequence " << k << "> Role: " << aId << ", Source: "<< aSourceRepr); + } + else + { + SAL_INFO("chart2", " <data sequence " << k << "> unknown Role, Source: " << aSourceRepr ); + } + + aSourceRepr = "<none>"; + if( aSequences[k]->getLabel().is()) + aSourceRepr = aSequences[k]->getLabel()->getSourceRangeRepresentation(); + xProp.set( aSequences[k]->getLabel(), uno::UNO_QUERY ); + if( xProp.is() && + ( xProp->getPropertyValue( "Role") >>= aId )) + { + SAL_INFO("chart2", " <data sequence label " << k << "> Role: " << aId + << ", Source: " << aSourceRepr ); + } + else + { + SAL_INFO("chart2", " <data sequence label " << k << "> unknown Role, Source: " << aSourceRepr ); + } + } + } +} + +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/DataInterpreter.hxx b/chart2/source/model/template/DataInterpreter.hxx new file mode 100644 index 000000000..72d3d61e4 --- /dev/null +++ b/chart2/source/model/template/DataInterpreter.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_DATAINTERPRETER_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_DATAINTERPRETER_HXX + +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/chart2/XDataInterpreter.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +namespace chart +{ + +class DataInterpreter : public ::cppu::WeakImplHelper< + css::chart2::XDataInterpreter, + css::lang::XServiceInfo > +{ +public: + explicit DataInterpreter(); + virtual ~DataInterpreter() override; + + /// XServiceInfo declarations + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // convenience methods + static OUString GetRole( const css::uno::Reference< css::chart2::data::XDataSequence > & xSeq ); + + static void SetRole( + const css::uno::Reference< css::chart2::data::XDataSequence > & xSeq, + const OUString & rRole ); + + static css::uno::Any GetProperty( + const css::uno::Sequence<css::beans::PropertyValue > & aArguments, + const OUString & rName ); + + static bool HasCategories( + const css::uno::Sequence< css::beans::PropertyValue > & rArguments, + const css::uno::Sequence< css::uno::Reference< css::chart2::data::XLabeledDataSequence > > & rData ); + + static bool UseCategoriesAsX( + const css::uno::Sequence< css::beans::PropertyValue > & rArguments ); + +protected: + // ____ XDataInterpreter ____ + virtual css::chart2::InterpretedData SAL_CALL interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const css::uno::Sequence< css::uno::Reference< css::chart2::XDataSeries > >& aSeriesToReUse ) override; + virtual css::chart2::InterpretedData SAL_CALL reinterpretDataSeries( + const css::chart2::InterpretedData& aInterpretedData ) override; + virtual sal_Bool SAL_CALL isDataCompatible( + const css::chart2::InterpretedData& aInterpretedData ) override; + virtual css::uno::Reference< css::chart2::data::XDataSource > SAL_CALL mergeInterpretedData( + const css::chart2::InterpretedData& aInterpretedData ) override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_DATAINTERPRETER_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/FilledNetChartType.cxx b/chart2/source/model/template/FilledNetChartType.cxx new file mode 100644 index 000000000..3179317da --- /dev/null +++ b/chart2/source/model/template/FilledNetChartType.cxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "FilledNetChartType.hxx" +#include <servicenames_charttypes.hxx> +#include <cppuhelper/supportsservice.hxx> + +namespace com::sun::star::uno { class XComponentContext; } + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; + +using ::com::sun::star::uno::Sequence; + +namespace chart +{ + +FilledNetChartType::FilledNetChartType() +{} + +FilledNetChartType::FilledNetChartType( const FilledNetChartType & rOther ) : + NetChartType_Base( rOther ) +{ +} + +FilledNetChartType::~FilledNetChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL FilledNetChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new FilledNetChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL FilledNetChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET; +} + +OUString SAL_CALL FilledNetChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.FilledNetChartType"; +} + +sal_Bool SAL_CALL FilledNetChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL FilledNetChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET, + "com.sun.star.chart2.ChartType", + "com.sun.star.beans.PropertySet" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_FilledNetChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::FilledNetChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/FilledNetChartType.hxx b/chart2/source/model/template/FilledNetChartType.hxx new file mode 100644 index 000000000..baa2b9efb --- /dev/null +++ b/chart2/source/model/template/FilledNetChartType.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_FILLEDNETCHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_FILLEDNETCHARTTYPE_HXX + +#include "NetChartType.hxx" + +namespace chart +{ + +class FilledNetChartType final : public NetChartType_Base +{ +public: + explicit FilledNetChartType(); + virtual ~FilledNetChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit FilledNetChartType( const FilledNetChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_FILLEDNETCHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/LineChartType.cxx b/chart2/source/model/template/LineChartType.cxx new file mode 100644 index 000000000..64b2fe9c1 --- /dev/null +++ b/chart2/source/model/template/LineChartType.cxx @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "LineChartType.hxx" +#include <PropertyHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <unonames.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/chart2/CurveStyle.hpp> + +namespace com::sun::star::uno { class XComponentContext; } + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; + +namespace +{ + +enum +{ + PROP_LINECHARTTYPE_CURVE_STYLE, + PROP_LINECHARTTYPE_CURVE_RESOLUTION, + PROP_LINECHARTTYPE_SPLINE_ORDER +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( CHART_UNONAME_CURVE_STYLE, + PROP_LINECHARTTYPE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + + rOutProperties.emplace_back( CHART_UNONAME_CURVE_RESOLUTION, + PROP_LINECHARTTYPE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( CHART_UNONAME_SPLINE_ORDER, + PROP_LINECHARTTYPE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticLineChartTypeDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINECHARTTYPE_CURVE_STYLE, ::chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINECHARTTYPE_CURVE_RESOLUTION, 20 ); + + // todo: check whether order 3 means polygons of order 3 or 2. (see + // http://www.people.nnov.ru/fractal/Splines/Basis.htm ) + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINECHARTTYPE_SPLINE_ORDER, 3 ); + } +}; + +struct StaticLineChartTypeDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticLineChartTypeDefaults_Initializer > +{ +}; + +struct StaticLineChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticLineChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticLineChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticLineChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticLineChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticLineChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticLineChartTypeInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +LineChartType::LineChartType() +{ +} + +LineChartType::LineChartType( const LineChartType & rOther ) : + ChartType( rOther ) +{ +} + +LineChartType::~LineChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL LineChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new LineChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL LineChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_LINE; +} + +// ____ OPropertySet ____ +uno::Any LineChartType::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticLineChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL LineChartType::getInfoHelper() +{ + return *StaticLineChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL LineChartType::getPropertySetInfo() +{ + return *StaticLineChartTypeInfo::get(); +} + +OUString SAL_CALL LineChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.LineChartType"; +} + +sal_Bool SAL_CALL LineChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL LineChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_LINE, + "com.sun.star.chart2.ChartType", + "com.sun.star.beans.PropertySet" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_LineChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::LineChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/LineChartType.hxx b/chart2/source/model/template/LineChartType.hxx new file mode 100644 index 000000000..27ebc7ffb --- /dev/null +++ b/chart2/source/model/template/LineChartType.hxx @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_LINECHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_LINECHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class LineChartType final : public ChartType +{ +public: + explicit LineChartType(); + virtual ~LineChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit LineChartType( const LineChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_LINECHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/LineChartTypeTemplate.cxx b/chart2/source/model/template/LineChartTypeTemplate.cxx new file mode 100644 index 000000000..7989a7435 --- /dev/null +++ b/chart2/source/model/template/LineChartTypeTemplate.cxx @@ -0,0 +1,374 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "LineChartTypeTemplate.hxx" +#include <DiagramHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <DataSeriesHelper.hxx> +#include <PropertyHelper.hxx> +#include <unonames.hxx> + +#include <com/sun/star/chart2/CurveStyle.hpp> +#include <com/sun/star/chart2/SymbolStyle.hpp> +#include <com/sun/star/chart2/Symbol.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +#include <algorithm> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::Property; + +namespace +{ + +enum +{ + PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE, + PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION, + PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER + +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( CHART_UNONAME_CURVE_STYLE, + PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( CHART_UNONAME_CURVE_RESOLUTION, + PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( CHART_UNONAME_SPLINE_ORDER, + PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticLineChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE, chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION, 20 ); + + // todo: check whether order 3 means polygons of order 3 or 2. (see + // http://www.people.nnov.ru/fractal/Splines/Basis.htm ) + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER, 3 ); + } +}; + +struct StaticLineChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticLineChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticLineChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticLineChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticLineChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticLineChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticLineChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticLineChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticLineChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +LineChartTypeTemplate::LineChartTypeTemplate( + uno::Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + bool bSymbols, + bool bHasLines /* = true */, + sal_Int32 nDim /* = 2 */ ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ), + m_eStackMode( eStackMode ), + m_bHasSymbols( bSymbols ), + m_bHasLines( bHasLines ), + m_nDim( nDim ) +{ + if( nDim == 3 ) + m_bHasSymbols = false; +} + +LineChartTypeTemplate::~LineChartTypeTemplate() +{} +// ____ OPropertySet ____ +uno::Any LineChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticLineChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL LineChartTypeTemplate::getInfoHelper() +{ + return *StaticLineChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL LineChartTypeTemplate::getPropertySetInfo() +{ + return *StaticLineChartTypeTemplateInfo::get(); +} + +sal_Int32 LineChartTypeTemplate::getDimension() const +{ + return m_nDim; +} + +StackMode LineChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + return m_eStackMode; +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL LineChartTypeTemplate::matchesTemplate( + const uno::Reference< chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties ); + + // check symbol-style and line-style + // for a template with symbols (or with lines) it is ok, if there is at least one series + // with symbols (or with lines) + if( bResult ) + { + bool bSymbolFound = false; + bool bLineFound = false; + + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + + for (auto const& series : aSeriesVec) + { + try + { + chart2::Symbol aSymbProp; + drawing::LineStyle eLineStyle; + Reference< beans::XPropertySet > xProp(series, uno::UNO_QUERY_THROW); + + bool bCurrentHasSymbol = (xProp->getPropertyValue( "Symbol") >>= aSymbProp) && + (aSymbProp.Style != chart2::SymbolStyle_NONE); + + if( bCurrentHasSymbol ) + bSymbolFound = true; + + if( bCurrentHasSymbol && (!m_bHasSymbols) ) + { + bResult = false; + break; + } + + bool bCurrentHasLine = (xProp->getPropertyValue( "LineStyle") >>= eLineStyle) && + ( eLineStyle != drawing::LineStyle_NONE ); + + if( bCurrentHasLine ) + bLineFound = true; + + if( bCurrentHasLine && (!m_bHasLines) ) + { + bResult = false; + break; + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + if(bResult) + { + if( !bLineFound && m_bHasLines && bSymbolFound ) + bResult = false; + else if( !bSymbolFound && m_bHasSymbols && bLineFound ) + bResult = false; + else if( !bLineFound && !bSymbolFound ) + return m_bHasLines && m_bHasSymbols; + } + } + + // adapt curve style, spline order and resolution + if( bResult && bAdaptProperties ) + { + try + { + uno::Reference< beans::XPropertySet > xChartTypeProp( + DiagramHelper::getChartTypeByIndex( xDiagram, 0 ), + uno::UNO_QUERY_THROW ); + setFastPropertyValue_NoBroadcast( PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE, xChartTypeProp->getPropertyValue(CHART_UNONAME_CURVE_STYLE) ); + setFastPropertyValue_NoBroadcast( PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION, xChartTypeProp->getPropertyValue(CHART_UNONAME_CURVE_RESOLUTION) ); + setFastPropertyValue_NoBroadcast( PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER, xChartTypeProp->getPropertyValue(CHART_UNONAME_SPLINE_ORDER) ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return bResult; +} + +Reference< chart2::XChartType > LineChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW ); + + Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE )); + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xCTProp->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XChartType > SAL_CALL LineChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW ); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + + Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE )); + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xCTProp->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +void SAL_CALL LineChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW ); + + DataSeriesHelper::switchSymbolsOnOrOff( xProp, m_bHasSymbols, nSeriesIndex ); + DataSeriesHelper::switchLinesOnOrOff( xProp, m_bHasLines ); + DataSeriesHelper::makeLinesThickOrThin( xProp, m_nDim==2 ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +IMPLEMENT_FORWARD_XINTERFACE2( LineChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( LineChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/LineChartTypeTemplate.hxx b/chart2/source/model/template/LineChartTypeTemplate.hxx new file mode 100644 index 000000000..2663fb113 --- /dev/null +++ b/chart2/source/model/template/LineChartTypeTemplate.hxx @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_LINECHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_LINECHARTTYPETEMPLATE_HXX + +#include "ChartTypeTemplate.hxx" +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <StackMode.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class LineChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + explicit LineChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + bool bSymbols, + bool bHasLines = true, + sal_Int32 nDim = 2 ); + virtual ~LineChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + + // ____ ChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + virtual sal_Int32 getDimension() const override; + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; + +private: + StackMode m_eStackMode; + bool m_bHasSymbols; + bool m_bHasLines; + sal_Int32 m_nDim; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_LINECHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/NetChartType.cxx b/chart2/source/model/template/NetChartType.cxx new file mode 100644 index 000000000..95de304b6 --- /dev/null +++ b/chart2/source/model/template/NetChartType.cxx @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "NetChartType.hxx" +#include <PolarCoordinateSystem.hxx> +#include <servicenames_charttypes.hxx> +#include <AxisIndexDefines.hxx> +#include <AxisHelper.hxx> + +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/chart2/AxisType.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace chart +{ + +NetChartType_Base::NetChartType_Base() +{} + +NetChartType_Base::NetChartType_Base( const NetChartType_Base & rOther ) : + ChartType( rOther ) +{ +} + +NetChartType_Base::~NetChartType_Base() +{} + +Reference< XCoordinateSystem > SAL_CALL + NetChartType_Base::createCoordinateSystem( ::sal_Int32 DimensionCount ) +{ + if( DimensionCount != 2 ) + throw lang::IllegalArgumentException( + "NetChart must be two-dimensional", + static_cast< ::cppu::OWeakObject* >( this ), 0 ); + + Reference< XCoordinateSystem > xResult( + new PolarCoordinateSystem( DimensionCount )); + + Reference< XAxis > xAxis( xResult->getAxisByDimension( 0, MAIN_AXIS_INDEX ) ); + if( xAxis.is() ) + { + ScaleData aScaleData = xAxis->getScaleData(); + aScaleData.Scaling = AxisHelper::createLinearScaling(); + aScaleData.AxisType = AxisType::CATEGORY; + aScaleData.Orientation = AxisOrientation_MATHEMATICAL; + xAxis->setScaleData( aScaleData ); + } + + xAxis = xResult->getAxisByDimension( 1, MAIN_AXIS_INDEX ); + if( xAxis.is() ) + { + ScaleData aScaleData = xAxis->getScaleData(); + aScaleData.Orientation = AxisOrientation_MATHEMATICAL; + aScaleData.AxisType = AxisType::REALNUMBER; + xAxis->setScaleData( aScaleData ); + } + + return xResult; +} + +// ____ OPropertySet ____ +uno::Any NetChartType_Base::GetDefaultValue( sal_Int32 /*nHandle*/ ) const +{ + return uno::Any(); +} + +namespace +{ + +struct StaticNetChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper(Sequence< beans::Property >{}); + return &aPropHelper; + } +}; + +struct StaticNetChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticNetChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticNetChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticNetChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticNetChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticNetChartTypeInfo_Initializer > +{ +}; + +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL NetChartType_Base::getInfoHelper() +{ + return *StaticNetChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL NetChartType_Base::getPropertySetInfo() +{ + return *StaticNetChartTypeInfo::get(); +} + +NetChartType::NetChartType() +{} + +NetChartType::NetChartType( const NetChartType & rOther ) : + NetChartType_Base( rOther ) +{ +} + +NetChartType::~NetChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL NetChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new NetChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL NetChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_NET; +} + +OUString SAL_CALL NetChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.NetChartType"; +} + +sal_Bool SAL_CALL NetChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL NetChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_NET, + "com.sun.star.chart2.ChartType", + "com.sun.star.beans.PropertySet" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_NetChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::NetChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/NetChartType.hxx b/chart2/source/model/template/NetChartType.hxx new file mode 100644 index 000000000..3d3efed8c --- /dev/null +++ b/chart2/source/model/template/NetChartType.hxx @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_NETCHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_NETCHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class NetChartType_Base : public ChartType +{ +public: + explicit NetChartType_Base(); + virtual ~NetChartType_Base() override; + +protected: + explicit NetChartType_Base( const NetChartType_Base & rOther ); + + // ____ XChartType ____ + virtual css::uno::Reference< css::chart2::XCoordinateSystem > SAL_CALL + createCoordinateSystem( ::sal_Int32 DimensionCount ) override; + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; +}; + +class NetChartType final : public NetChartType_Base +{ +public: + explicit NetChartType(); + virtual ~NetChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit NetChartType( const NetChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_NETCHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/NetChartTypeTemplate.cxx b/chart2/source/model/template/NetChartTypeTemplate.cxx new file mode 100644 index 000000000..fed499cb3 --- /dev/null +++ b/chart2/source/model/template/NetChartTypeTemplate.cxx @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "NetChartTypeTemplate.hxx" +#include <DiagramHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <DataSeriesHelper.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/chart2/SymbolStyle.hpp> +#include <com/sun/star/chart2/Symbol.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +namespace chart +{ + +NetChartTypeTemplate::NetChartTypeTemplate( + Reference< uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + bool bSymbols, + bool bHasLines , + bool bHasFilledArea ) : + ChartTypeTemplate( xContext, rServiceName ), + m_eStackMode( eStackMode ), + m_bHasSymbols( bSymbols ), + m_bHasLines( bHasLines ), + m_bHasFilledArea( bHasFilledArea ) +{} + +NetChartTypeTemplate::~NetChartTypeTemplate() +{} + +StackMode NetChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + return m_eStackMode; +} + +void SAL_CALL NetChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW ); + + DataSeriesHelper::switchSymbolsOnOrOff( xProp, m_bHasSymbols, nSeriesIndex ); + DataSeriesHelper::switchLinesOnOrOff( xProp, m_bHasLines ); + DataSeriesHelper::makeLinesThickOrThin( xProp, true ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL NetChartTypeTemplate::matchesTemplate( + const Reference< chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties ); + + uno::Reference< beans::XPropertySet > xChartTypeProp( + DiagramHelper::getChartTypeByIndex( xDiagram, 0 ), uno::UNO_QUERY_THROW ); + + if( bResult ) + { + //filled net chart?: + if( m_bHasFilledArea ) + return true; + + // check symbol-style + // for a template with symbols it is ok, if there is at least one series + // with symbols, otherwise an unknown template is too easy to achieve + bool bSymbolFound = false; + bool bLineFound = false; + + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + + for (auto const& series : aSeriesVec) + { + try + { + chart2::Symbol aSymbProp; + drawing::LineStyle eLineStyle; + Reference< beans::XPropertySet > xProp(series, uno::UNO_QUERY_THROW); + + bool bCurrentHasSymbol = (xProp->getPropertyValue( "Symbol") >>= aSymbProp) && + (aSymbProp.Style != chart2::SymbolStyle_NONE); + + if( bCurrentHasSymbol ) + bSymbolFound = true; + + if( bCurrentHasSymbol && (!m_bHasSymbols) ) + { + bResult = false; + break; + } + + bool bCurrentHasLine = (xProp->getPropertyValue( "LineStyle") >>= eLineStyle) && + ( eLineStyle != drawing::LineStyle_NONE ); + + if( bCurrentHasLine ) + bLineFound = true; + + if( bCurrentHasLine && (!m_bHasLines) ) + { + bResult = false; + break; + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + if(bResult) + { + if( !bLineFound && m_bHasLines && bSymbolFound ) + bResult = false; + else if( !bSymbolFound && m_bHasSymbols && bLineFound ) + bResult = false; + else if( !bLineFound && !bSymbolFound ) + return m_bHasLines && m_bHasSymbols; + } + } + + return bResult; +} + +Reference< chart2::XChartType > NetChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + + if( m_bHasFilledArea ) + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET ), uno::UNO_QUERY_THROW ); + else + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_NET ), uno::UNO_QUERY_THROW ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XChartType > SAL_CALL NetChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult( getChartTypeForIndex( 0 ) ); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + return xResult; +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/NetChartTypeTemplate.hxx b/chart2/source/model/template/NetChartTypeTemplate.hxx new file mode 100644 index 000000000..369989e6f --- /dev/null +++ b/chart2/source/model/template/NetChartTypeTemplate.hxx @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_NETCHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_NETCHARTTYPETEMPLATE_HXX + +#include "ChartTypeTemplate.hxx" +#include <StackMode.hxx> + +namespace chart +{ + +class NetChartTypeTemplate : public ChartTypeTemplate +{ +public: + explicit NetChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StackMode eStackMode, + bool bSymbols, + bool bHasLines = true, + bool bHasFilledArea = false + ); + virtual ~NetChartTypeTemplate() override; + +protected: + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + + // ____ ChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; + +private: + StackMode m_eStackMode; + bool m_bHasSymbols; + bool m_bHasLines; + bool m_bHasFilledArea; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_NETCHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/PieChartType.cxx b/chart2/source/model/template/PieChartType.cxx new file mode 100644 index 000000000..c18c8d11d --- /dev/null +++ b/chart2/source/model/template/PieChartType.cxx @@ -0,0 +1,241 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "PieChartType.hxx" +#include <PropertyHelper.hxx> +#include <PolarCoordinateSystem.hxx> +#include <AxisHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <AxisIndexDefines.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/chart2/AxisType.hpp> + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace +{ + +enum +{ + PROP_PIECHARTTYPE_USE_RINGS, + PROP_PIECHARTTYPE_3DRELATIVEHEIGHT +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "UseRings", + PROP_PIECHARTTYPE_USE_RINGS, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "3DRelativeHeight", + PROP_PIECHARTTYPE_3DRELATIVEHEIGHT, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::MAYBEVOID ); +} + +struct StaticPieChartTypeDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_PIECHARTTYPE_USE_RINGS, false ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_PIECHARTTYPE_3DRELATIVEHEIGHT, 100 ); + } +}; + +struct StaticPieChartTypeDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticPieChartTypeDefaults_Initializer > +{ +}; + +struct StaticPieChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticPieChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticPieChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticPieChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticPieChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticPieChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticPieChartTypeInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +PieChartType::PieChartType() +{ +} + +PieChartType::PieChartType( const PieChartType & rOther ) : + ChartType( rOther ) +{ +} + +PieChartType::~PieChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL PieChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new PieChartType( *this )); +} + +// ____ XChartType ____ +OUString SAL_CALL PieChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_PIE; +} + +Reference< chart2::XCoordinateSystem > SAL_CALL + PieChartType::createCoordinateSystem( ::sal_Int32 DimensionCount ) +{ + Reference< chart2::XCoordinateSystem > xResult( + new PolarCoordinateSystem( DimensionCount )); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + Reference< chart2::XAxis > xAxis( xResult->getAxisByDimension( i, MAIN_AXIS_INDEX ) ); + if( !xAxis.is() ) + { + OSL_FAIL("a created coordinate system should have an axis for each dimension"); + continue; + } + + //hhhh todo make axis invisible + + chart2::ScaleData aScaleData = xAxis->getScaleData(); + aScaleData.Scaling = AxisHelper::createLinearScaling(); + aScaleData.AxisType = chart2::AxisType::REALNUMBER; + + if( i == 0 ) + aScaleData.Orientation = chart2::AxisOrientation_REVERSE; + else + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + + //remove explicit scalings from all axes + AxisHelper::removeExplicitScaling( aScaleData ); + + xAxis->setScaleData( aScaleData ); + } + + return xResult; +} + +uno::Sequence< OUString > PieChartType::getSupportedPropertyRoles() +{ + uno::Sequence< OUString > aPropRoles(2); + aPropRoles[0] = "FillColor"; + aPropRoles[1] = "BorderColor"; + + return aPropRoles; +} + +// ____ OPropertySet ____ +uno::Any PieChartType::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticPieChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL PieChartType::getInfoHelper() +{ + return *StaticPieChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL PieChartType::getPropertySetInfo() +{ + return *StaticPieChartTypeInfo::get(); +} + +OUString SAL_CALL PieChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.PieChartType"; +} + +sal_Bool SAL_CALL PieChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL PieChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_PIE, + "com.sun.star.chart2.ChartType", + "com.sun.star.beans.PropertySet" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_PieChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::PieChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/PieChartType.hxx b/chart2/source/model/template/PieChartType.hxx new file mode 100644 index 000000000..897ec9695 --- /dev/null +++ b/chart2/source/model/template/PieChartType.hxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_PIECHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_PIECHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class PieChartType final: public ChartType +{ +public: + explicit PieChartType(); + virtual ~PieChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit PieChartType( const PieChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Reference< css::chart2::XCoordinateSystem > SAL_CALL + createCoordinateSystem( ::sal_Int32 DimensionCount ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedPropertyRoles() override; + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + + // ____ OPropertySet ____ + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_PIECHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/PieChartTypeTemplate.cxx b/chart2/source/model/template/PieChartTypeTemplate.cxx new file mode 100644 index 000000000..964b5d96d --- /dev/null +++ b/chart2/source/model/template/PieChartTypeTemplate.cxx @@ -0,0 +1,608 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "PieChartTypeTemplate.hxx" +#include <CommonConverters.hxx> +#include <DiagramHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <DataSeriesHelper.hxx> +#include <AxisHelper.hxx> +#include <ThreeDHelper.hxx> +#include <PropertyHelper.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/chart2/XChartTypeContainer.hpp> +#include <com/sun/star/chart2/XDataSeriesContainer.hpp> +#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +#include <rtl/math.hxx> + +#include <algorithm> + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace +{ + +enum +{ + PROP_PIE_TEMPLATE_DEFAULT_OFFSET, + PROP_PIE_TEMPLATE_OFFSET_MODE, + PROP_PIE_TEMPLATE_DIMENSION, + PROP_PIE_TEMPLATE_USE_RINGS +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "OffsetMode", + PROP_PIE_TEMPLATE_OFFSET_MODE, + cppu::UnoType<chart2::PieChartOffsetMode>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "DefaultOffset", + PROP_PIE_TEMPLATE_DEFAULT_OFFSET, + cppu::UnoType<double>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "Dimension", + PROP_PIE_TEMPLATE_DIMENSION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "UseRings", + PROP_PIE_TEMPLATE_USE_RINGS, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticPieChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_PIE_TEMPLATE_OFFSET_MODE, chart2::PieChartOffsetMode_NONE ); + ::chart::PropertyHelper::setPropertyValueDefault< double >( rOutMap, PROP_PIE_TEMPLATE_DEFAULT_OFFSET, 0.5 ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_PIE_TEMPLATE_DIMENSION, 2 ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_PIE_TEMPLATE_USE_RINGS, false ); + } +}; + +struct StaticPieChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticPieChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticPieChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static uno::Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticPieChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticPieChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticPieChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticPieChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticPieChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticPieChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +PieChartTypeTemplate::PieChartTypeTemplate( + uno::Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName, + chart2::PieChartOffsetMode eMode, + bool bRings /* = false */, + sal_Int32 nDim /* = 2 */ ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ) +{ + setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_OFFSET_MODE, uno::Any( eMode )); + setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_DIMENSION, uno::Any( nDim )); + setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_USE_RINGS, uno::Any( bRings )); +} + +PieChartTypeTemplate::~PieChartTypeTemplate() +{} + +// ____ OPropertySet ____ +uno::Any PieChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticPieChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL PieChartTypeTemplate::getInfoHelper() +{ + return *StaticPieChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL PieChartTypeTemplate::getPropertySetInfo() +{ + return *StaticPieChartTypeTemplateInfo::get(); +} + +// ____ ChartTypeTemplate ____ +sal_Int32 PieChartTypeTemplate::getDimension() const +{ + sal_Int32 nDim = 2; + try + { + // note: UNO-methods are never const + const_cast< PieChartTypeTemplate * >( this )-> + getFastPropertyValue( PROP_PIE_TEMPLATE_DIMENSION ) >>= nDim; + } + catch( const beans::UnknownPropertyException & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return nDim; +} + +sal_Int32 PieChartTypeTemplate::getAxisCountByDimension( sal_Int32 /*nDimension*/ ) +{ + return 0; +} + +void PieChartTypeTemplate::adaptAxes( + const uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > & /*rCoordSys*/ ) +{ + // hide existing axes + //hhhh todo +} + +void PieChartTypeTemplate::adaptScales( + const Sequence< Reference< chart2::XCoordinateSystem > > & aCooSysSeq, + const Reference< chart2::data::XLabeledDataSequence > & xCategories //@todo: in future there may be more than one sequence of categories (e.g. charttype with categories at x and y axis ) + ) +{ + ChartTypeTemplate::adaptScales( aCooSysSeq, xCategories ); + + //remove explicit scalings from radius axis + //and ensure correct orientation of scales for donuts + + for( Reference< chart2::XCoordinateSystem > const & coords : aCooSysSeq ) + { + try + { + Reference< chart2::XAxis > xAxis( AxisHelper::getAxis( 1 /*nDimensionIndex*/,0 /*nAxisIndex*/ + , coords ) ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData() ); + AxisHelper::removeExplicitScaling( aScaleData ); + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + xAxis->setScaleData( aScaleData ); + } + + xAxis = AxisHelper::getAxis( 0 /*nDimensionIndex*/,0 /*nAxisIndex*/ + , coords ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData() ); + aScaleData.Orientation = chart2::AxisOrientation_REVERSE; + xAxis->setScaleData( aScaleData ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } +} + +void PieChartTypeTemplate::createChartTypes( + const Sequence< Sequence< Reference< chart2::XDataSeries > > > & aSeriesSeq, + const Sequence< Reference< chart2::XCoordinateSystem > > & rCoordSys, + const Sequence< Reference< chart2::XChartType > >& /* aOldChartTypesSeq */ ) +{ + if( ! rCoordSys.hasElements() || + ! rCoordSys[0].is() ) + return; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + + Reference< chart2::XChartType > xCT( + xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_PIE ), uno::UNO_QUERY_THROW ); + Reference< beans::XPropertySet > xCTProp( xCT, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( + "UseRings", getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); + } + Reference< chart2::XChartTypeContainer > xCTCnt( rCoordSys[0], uno::UNO_QUERY_THROW ); + xCTCnt->setChartTypes( Sequence< Reference< chart2::XChartType > >( &xCT, 1 )); + + if( aSeriesSeq.hasElements() ) + { + Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + Sequence< Reference< chart2::XDataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq )); + xDSCnt->setDataSeries( aFlatSeriesSeq ); + + DataSeriesHelper::setStackModeAtSeries( + aFlatSeriesSeq, rCoordSys[0], getStackMode( 0 )); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL PieChartTypeTemplate::matchesTemplate( + const uno::Reference< chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties ); + + bool bTemplateUsesRings = false; + getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ) >>= bTemplateUsesRings; + chart2::PieChartOffsetMode ePieOffsetMode; + getFastPropertyValue( PROP_PIE_TEMPLATE_OFFSET_MODE ) >>= ePieOffsetMode; + + //check offset-mode + if( bResult ) + { + try + { + double fOffset=0.0; + bool bAllOffsetsEqual = true; + + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + + //check offset of outer series + if( !aSeriesVec.empty() ) + { + //@todo in future this will depend on Orientation of the radius axis scale + Reference< chart2::XDataSeries > xSeries( aSeriesVec[0] ); + Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW ); + xProp->getPropertyValue( "Offset") >>= fOffset; + + //get AttributedDataPoints + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList ) + { + for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) + { + uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) ); + if(xPointProp.is()) + { + double fPointOffset=0.0; + if( xProp->getPropertyValue( "Offset") >>= fPointOffset ) + { + if( ! ::rtl::math::approxEqual( fPointOffset, fOffset ) ) + { + bAllOffsetsEqual = false; + break; + } + } + } + } + } + } + + chart2::PieChartOffsetMode eOffsetMode = chart2::PieChartOffsetMode_NONE; + if( bAllOffsetsEqual && fOffset > 0.0 ) + { + eOffsetMode = chart2::PieChartOffsetMode_ALL_EXPLODED; + if( bAdaptProperties ) + setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_DEFAULT_OFFSET, uno::Any( fOffset )); + } + + bResult = ( eOffsetMode == ePieOffsetMode ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + bResult = false; + } + } + + //check UseRings + if( bResult ) + { + uno::Reference< beans::XPropertySet > xCTProp( + DiagramHelper::getChartTypeByIndex( xDiagram, 0 ), uno::UNO_QUERY_THROW ); + bool bUseRings = false; + if( xCTProp->getPropertyValue( "UseRings") >>= bUseRings ) + { + bResult = ( bTemplateUsesRings == bUseRings ); + } + } + + return bResult; +} + +Reference< chart2::XChartType > PieChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_PIE ), uno::UNO_QUERY_THROW ); + Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( + "UseRings", getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); + } + + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XChartType > SAL_CALL PieChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_PIE ), uno::UNO_QUERY_THROW ); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( + "UseRings", getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); + } + + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +void SAL_CALL PieChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW ); + + bool bTemplateUsesRings = false; + getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ) >>= bTemplateUsesRings; + if( nSeriesIndex == 0 ) //@todo in future this will depend on Orientation of the radius axis scale + { + const OUString aOffsetPropName( "Offset" ); + // get offset mode + chart2::PieChartOffsetMode ePieOffsetMode; + getFastPropertyValue( PROP_PIE_TEMPLATE_OFFSET_MODE ) >>= ePieOffsetMode; + + // get default offset + double fDefaultOffset = 0.5; + getFastPropertyValue( PROP_PIE_TEMPLATE_DEFAULT_OFFSET ) >>= fDefaultOffset; + double fOffsetToSet = fDefaultOffset; + + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + xProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList; + + // determine whether to set the new offset + bool bSetOffset = ( ePieOffsetMode == chart2::PieChartOffsetMode_ALL_EXPLODED ); + if( !bSetOffset && + (ePieOffsetMode == chart2::PieChartOffsetMode_NONE) ) + { + // set offset to 0 if the offset was exactly "all exploded" + // before (individual offsets are kept) + double fOffset = 0.0; + if( (xProp->getPropertyValue( aOffsetPropName ) >>= fOffset) && + ::rtl::math::approxEqual( fOffset, fDefaultOffset )) + { + fOffsetToSet = 0.0; + bSetOffset = true; + for( auto const & pointIndex : std::as_const(aAttributedDataPointIndexList) ) + { + uno::Reference< beans::XPropertySet > xPointProp( + xSeries->getDataPointByIndex( pointIndex )); + uno::Reference< beans::XPropertyState > xPointState( xPointProp, uno::UNO_QUERY ); + double fPointOffset = 0.0; + if( xPointState.is() && + (xPointState->getPropertyState( aOffsetPropName ) == beans::PropertyState_DIRECT_VALUE) && + xPointProp.is() && + (xPointProp->getPropertyValue( aOffsetPropName ) >>= fPointOffset ) && + ! ::rtl::math::approxEqual( fPointOffset, fDefaultOffset ) ) + { + bSetOffset = false; + break; + } + } + } + } + + if( bSetOffset ) + { + // set the offset to the series and to the attributed data points + xProp->setPropertyValue( aOffsetPropName, uno::Any( fOffsetToSet )); + + // remove hard attributes from data points + for( auto const & pointIndex : std::as_const(aAttributedDataPointIndexList) ) + { + uno::Reference< beans::XPropertyState > xPointState( + xSeries->getDataPointByIndex( pointIndex ), uno::UNO_QUERY ); + if( xPointState.is()) + xPointState->setPropertyToDefault( aOffsetPropName ); + } + } + } + + // line style + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); + + // vary colors by point + xProp->setPropertyValue( "VaryColorsByPoint", uno::Any( true )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void SAL_CALL PieChartTypeTemplate::resetStyles( const Reference< chart2::XDiagram >& xDiagram ) +{ + // reset axes and grids + Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY ); + if( xCooSysCnt.is()) + { + const Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems()); + ChartTypeTemplate::createAxes( aCooSysSeq ); + + //reset scale orientation + for( Reference< chart2::XCoordinateSystem > const & coords : aCooSysSeq ) + { + try + { + Reference< chart2::XAxis > xAxis( AxisHelper::getAxis( 0 /*nDimensionIndex*/,0 /*nAxisIndex*/ + , coords ) ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData() ); + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + xAxis->setScaleData( aScaleData ); + } + + xAxis = AxisHelper::getAxis( 1, 0, coords ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData() ); + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + xAxis->setScaleData( aScaleData ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + + ChartTypeTemplate::resetStyles( xDiagram ); + + // vary colors by point, + // line style + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + uno::Any aLineStyleAny( drawing::LineStyle_NONE ); + for (auto const& series : aSeriesVec) + { + Reference< beans::XPropertyState > xState(series, uno::UNO_QUERY); + if( xState.is()) + { + xState->setPropertyToDefault( "VaryColorsByPoint"); + Reference< beans::XPropertySet > xProp( xState, uno::UNO_QUERY ); + if( xProp.is() && + xProp->getPropertyValue( "BorderStyle") == aLineStyleAny ) + { + xState->setPropertyToDefault( "BorderStyle"); + } + } + } + + //reset scene properties + ThreeDHelper::setDefaultRotation( uno::Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY ), false ); +} + +// ____ XChartTypeTemplate ____ +void PieChartTypeTemplate::adaptDiagram( const uno::Reference< chart2::XDiagram >& xDiagram ) +{ + if( !xDiagram.is() ) + return; + + //different default for scene geometry: + ThreeDHelper::setDefaultRotation( uno::Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY ), true ); +} + +IMPLEMENT_FORWARD_XINTERFACE2( PieChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( PieChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/PieChartTypeTemplate.hxx b/chart2/source/model/template/PieChartTypeTemplate.hxx new file mode 100644 index 000000000..f11099fdd --- /dev/null +++ b/chart2/source/model/template/PieChartTypeTemplate.hxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_PIECHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_PIECHARTTYPETEMPLATE_HXX + +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <comphelper/uno3.hxx> + +#include "ChartTypeTemplate.hxx" +#include <com/sun/star/chart2/PieChartOffsetMode.hpp> + +namespace chart +{ + +class PieChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + PieChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + css::chart2::PieChartOffsetMode eMode, + bool bRings, + sal_Int32 nDim = 2 ); + virtual ~PieChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< + css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void SAL_CALL resetStyles( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) override; + + // ____ ChartTypeTemplate ____ + virtual sal_Int32 getDimension() const override; + + virtual void adaptDiagram( + const css::uno::Reference< css::chart2::XDiagram > & xDiagram ) override; + + virtual sal_Int32 getAxisCountByDimension( sal_Int32 nDimension ) override; + + virtual void adaptAxes( + const css::uno::Sequence< css::uno::Reference< css::chart2::XCoordinateSystem > > & rCoordSys ) override; + + virtual void adaptScales( + const css::uno::Sequence< css::uno::Reference< css::chart2::XCoordinateSystem > > & aCooSysSeq, + const css::uno::Reference< css::chart2::data::XLabeledDataSequence > & xCategories ) override; + + virtual void createChartTypes( + const css::uno::Sequence< + css::uno::Sequence< + css::uno::Reference< + css::chart2::XDataSeries > > >& aSeriesSeq, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XCoordinateSystem > > & rCoordSys, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XChartType > > & aOldChartTypesSeq + ) override; + + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_PIECHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ScatterChartType.cxx b/chart2/source/model/template/ScatterChartType.cxx new file mode 100644 index 000000000..10798f9bd --- /dev/null +++ b/chart2/source/model/template/ScatterChartType.cxx @@ -0,0 +1,251 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ScatterChartType.hxx" +#include <PropertyHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <CartesianCoordinateSystem.hxx> +#include <AxisHelper.hxx> +#include <AxisIndexDefines.hxx> +#include <unonames.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/chart2/AxisType.hpp> +#include <com/sun/star/chart2/CurveStyle.hpp> + +using namespace ::com::sun::star; + +using ::com::sun::star::beans::Property; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Reference; + +namespace +{ + +enum +{ + PROP_SCATTERCHARTTYPE_CURVE_STYLE, + PROP_SCATTERCHARTTYPE_CURVE_RESOLUTION, + PROP_SCATTERCHARTTYPE_SPLINE_ORDER +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( CHART_UNONAME_CURVE_STYLE, + PROP_SCATTERCHARTTYPE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + + rOutProperties.emplace_back( CHART_UNONAME_CURVE_RESOLUTION, + PROP_SCATTERCHARTTYPE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( CHART_UNONAME_SPLINE_ORDER, + PROP_SCATTERCHARTTYPE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticScatterChartTypeDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCATTERCHARTTYPE_CURVE_STYLE, chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCATTERCHARTTYPE_CURVE_RESOLUTION, 20 ); + + // todo: check whether order 3 means polygons of order 3 or 2. (see + // http://www.people.nnov.ru/fractal/Splines/Basis.htm ) + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCATTERCHARTTYPE_SPLINE_ORDER, 3 ); + } +}; + +struct StaticScatterChartTypeDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticScatterChartTypeDefaults_Initializer > +{ +}; + +struct StaticScatterChartTypeInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticScatterChartTypeInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticScatterChartTypeInfoHelper_Initializer > +{ +}; + +struct StaticScatterChartTypeInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticScatterChartTypeInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticScatterChartTypeInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticScatterChartTypeInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +ScatterChartType::ScatterChartType() +{ +} + +ScatterChartType::ScatterChartType( const ScatterChartType & rOther ) : + ChartType( rOther ) +{ +} + +ScatterChartType::~ScatterChartType() +{} + +// ____ XCloneable ____ +uno::Reference< util::XCloneable > SAL_CALL ScatterChartType::createClone() +{ + return uno::Reference< util::XCloneable >( new ScatterChartType( *this )); +} + +// ____ XChartType ____ +Reference< chart2::XCoordinateSystem > SAL_CALL + ScatterChartType::createCoordinateSystem( ::sal_Int32 DimensionCount ) +{ + Reference< chart2::XCoordinateSystem > xResult( + new CartesianCoordinateSystem( DimensionCount )); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + Reference< chart2::XAxis > xAxis( xResult->getAxisByDimension( i, MAIN_AXIS_INDEX ) ); + if( !xAxis.is() ) + { + OSL_FAIL("a created coordinate system should have an axis for each dimension"); + continue; + } + + chart2::ScaleData aScaleData = xAxis->getScaleData(); + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + aScaleData.Scaling = AxisHelper::createLinearScaling(); + + if( i == 2 ) + aScaleData.AxisType = chart2::AxisType::SERIES; + else + aScaleData.AxisType = chart2::AxisType::REALNUMBER; + + xAxis->setScaleData( aScaleData ); + } + + return xResult; +} + +OUString SAL_CALL ScatterChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_SCATTER; +} + +uno::Sequence< OUString > SAL_CALL ScatterChartType::getSupportedMandatoryRoles() +{ + uno::Sequence< OUString > aMandRolesSeq(3); + aMandRolesSeq[0] = "label"; + aMandRolesSeq[1] = "values-x"; + aMandRolesSeq[2] = "values-y"; + return aMandRolesSeq; +} + +// ____ OPropertySet ____ +uno::Any ScatterChartType::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticScatterChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL ScatterChartType::getInfoHelper() +{ + return *StaticScatterChartTypeInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ScatterChartType::getPropertySetInfo() +{ + return *StaticScatterChartTypeInfo::get(); +} + +OUString SAL_CALL ScatterChartType::getImplementationName() +{ + return "com.sun.star.comp.chart.ScatterChartType"; +} + +sal_Bool SAL_CALL ScatterChartType::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence< OUString > SAL_CALL ScatterChartType::getSupportedServiceNames() +{ + return { + CHART2_SERVICE_NAME_CHARTTYPE_SCATTER, + "com.sun.star.chart2.ChartType", + "com.sun.star.beans.PropertySet" }; +} + +} // namespace chart + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_chart_ScatterChartType_get_implementation(css::uno::XComponentContext * /*context*/, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new ::chart::ScatterChartType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ScatterChartType.hxx b/chart2/source/model/template/ScatterChartType.hxx new file mode 100644 index 000000000..e7f1e24de --- /dev/null +++ b/chart2/source/model/template/ScatterChartType.hxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_SCATTERCHARTTYPE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_SCATTERCHARTTYPE_HXX + +#include "ChartType.hxx" + +namespace chart +{ + +class ScatterChartType final : public ChartType +{ +public: + ScatterChartType(); + virtual ~ScatterChartType() override; + + virtual OUString SAL_CALL + getImplementationName() override; + virtual sal_Bool SAL_CALL + supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() override; + +private: + explicit ScatterChartType( const ScatterChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedMandatoryRoles() override; + virtual css::uno::Reference< css::chart2::XCoordinateSystem > SAL_CALL + createCoordinateSystem( ::sal_Int32 DimensionCount ) override; + + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + + // ____ OPropertySet ____ + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XCloneable ____ + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_SCATTERCHARTTYPE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ScatterChartTypeTemplate.cxx b/chart2/source/model/template/ScatterChartTypeTemplate.cxx new file mode 100644 index 000000000..e0dc1cd11 --- /dev/null +++ b/chart2/source/model/template/ScatterChartTypeTemplate.cxx @@ -0,0 +1,391 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ScatterChartTypeTemplate.hxx" +#include "XYDataInterpreter.hxx" +#include <DiagramHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <DataSeriesHelper.hxx> +#include <PropertyHelper.hxx> +#include <unonames.hxx> + +#include <com/sun/star/chart2/CurveStyle.hpp> +#include <com/sun/star/chart2/SymbolStyle.hpp> +#include <com/sun/star/chart2/Symbol.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +#include <algorithm> + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::Property; + +namespace +{ + +enum +{ + PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, + PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION, + PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER + +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( CHART_UNONAME_CURVE_STYLE, + PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( CHART_UNONAME_CURVE_RESOLUTION, + PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( CHART_UNONAME_SPLINE_ORDER, + PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticScatterChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION, 20 ); + + // todo: check whether order 3 means polygons of order 3 or 2. (see + // http://www.people.nnov.ru/fractal/Splines/Basis.htm ) + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER, 3 ); + } +}; + +struct StaticScatterChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticScatterChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticScatterChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } + +}; + +struct StaticScatterChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticScatterChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticScatterChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticScatterChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticScatterChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticScatterChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +ScatterChartTypeTemplate::ScatterChartTypeTemplate( + Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName, + bool bSymbols, + bool bHasLines /* = true */, + sal_Int32 nDim /* = 2 */ ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ), + m_bHasSymbols( bSymbols ), + m_bHasLines( bHasLines ), + m_nDim( nDim ) +{ + if( nDim == 3 ) + m_bHasSymbols = false; +} + +ScatterChartTypeTemplate::~ScatterChartTypeTemplate() +{} + +// ____ OPropertySet ____ +uno::Any ScatterChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticScatterChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL ScatterChartTypeTemplate::getInfoHelper() +{ + return *StaticScatterChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ScatterChartTypeTemplate::getPropertySetInfo() +{ + return *StaticScatterChartTypeTemplateInfo::get(); +} + +sal_Int32 ScatterChartTypeTemplate::getDimension() const +{ + return m_nDim; +} + +StackMode ScatterChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + if( m_nDim == 3 ) + return StackMode::ZStacked; + return StackMode::NONE; +} + +void SAL_CALL ScatterChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW ); + + DataSeriesHelper::switchSymbolsOnOrOff( xProp, m_bHasSymbols, nSeriesIndex ); + DataSeriesHelper::switchLinesOnOrOff( xProp, m_bHasLines ); + DataSeriesHelper::makeLinesThickOrThin( xProp, m_nDim==2 ); + if( m_nDim==3 ) + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL ScatterChartTypeTemplate::supportsCategories() +{ + return false; +} + +sal_Bool SAL_CALL ScatterChartTypeTemplate::matchesTemplate( + const Reference< chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate( xDiagram, bAdaptProperties ); + + // check symbol-style and line-style + // for a template with symbols (or with lines) it is ok, if there is at least one series + // with symbols (or with lines) + if( bResult ) + { + bool bSymbolFound = false; + bool bLineFound = false; + + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + + for (auto const& series : aSeriesVec) + { + try + { + chart2::Symbol aSymbProp; + drawing::LineStyle eLineStyle; + Reference< beans::XPropertySet > xProp(series, uno::UNO_QUERY_THROW); + + bool bCurrentHasSymbol = (xProp->getPropertyValue( "Symbol") >>= aSymbProp) && + (aSymbProp.Style != chart2::SymbolStyle_NONE); + + if( bCurrentHasSymbol ) + bSymbolFound = true; + + if( bCurrentHasSymbol && (!m_bHasSymbols) ) + { + bResult = false; + break; + } + + bool bCurrentHasLine = (xProp->getPropertyValue( "LineStyle") >>= eLineStyle) && + ( eLineStyle != drawing::LineStyle_NONE ); + + if( bCurrentHasLine ) + bLineFound = true; + + if( bCurrentHasLine && (!m_bHasLines) ) + { + bResult = false; + break; + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + if(bResult) + { + if( !bLineFound && m_bHasLines && bSymbolFound ) + bResult = false; + else if( !bSymbolFound && m_bHasSymbols && bLineFound ) + bResult = false; + else if( !bLineFound && !bSymbolFound ) + return m_bHasLines && m_bHasSymbols; + } + } + + // adapt curve style, spline order and resolution + if( bResult && bAdaptProperties ) + { + try + { + uno::Reference< beans::XPropertySet > xChartTypeProp( + DiagramHelper::getChartTypeByIndex( xDiagram, 0 ), + uno::UNO_QUERY_THROW ); + setFastPropertyValue_NoBroadcast( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, xChartTypeProp->getPropertyValue(CHART_UNONAME_CURVE_STYLE) ); + setFastPropertyValue_NoBroadcast( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION, xChartTypeProp->getPropertyValue(CHART_UNONAME_CURVE_RESOLUTION) ); + setFastPropertyValue_NoBroadcast( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER, xChartTypeProp->getPropertyValue(CHART_UNONAME_SPLINE_ORDER) ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return bResult; +} + +Reference< chart2::XChartType > ScatterChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_SCATTER ), uno::UNO_QUERY_THROW ); + + Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE )); + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xCTProp->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XChartType > SAL_CALL ScatterChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_SCATTER ), uno::UNO_QUERY_THROW ); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + + Reference< beans::XPropertySet > xCTProp( xResult, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE )); + xCTProp->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xCTProp->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< chart2::XDataInterpreter > SAL_CALL ScatterChartTypeTemplate::getDataInterpreter() +{ + if( ! m_xDataInterpreter.is()) + m_xDataInterpreter.set( new XYDataInterpreter ); + + return m_xDataInterpreter; +} + +IMPLEMENT_FORWARD_XINTERFACE2( ScatterChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScatterChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/ScatterChartTypeTemplate.hxx b/chart2/source/model/template/ScatterChartTypeTemplate.hxx new file mode 100644 index 000000000..ee32e200f --- /dev/null +++ b/chart2/source/model/template/ScatterChartTypeTemplate.hxx @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_SCATTERCHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_SCATTERCHARTTYPETEMPLATE_HXX + +#include "ChartTypeTemplate.hxx" +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class ScatterChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + explicit ScatterChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + bool bSymbols, + bool bHasLines = true, + sal_Int32 nDim = 2 ); + virtual ~ScatterChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL supportsCategories() override; + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< + css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual css::uno::Reference< css::chart2::XDataInterpreter > SAL_CALL getDataInterpreter() override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + + // ____ ChartTypeTemplate ____ + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + virtual sal_Int32 getDimension() const override; + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; + +private: + bool m_bHasSymbols; + bool m_bHasLines; + sal_Int32 m_nDim; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_SCATTERCHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/StockChartTypeTemplate.cxx b/chart2/source/model/template/StockChartTypeTemplate.cxx new file mode 100644 index 000000000..7eb0e1ca5 --- /dev/null +++ b/chart2/source/model/template/StockChartTypeTemplate.cxx @@ -0,0 +1,499 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "StockChartTypeTemplate.hxx" +#include <DataSeriesHelper.hxx> +#include "StockDataInterpreter.hxx" +#include <DiagramHelper.hxx> +#include <servicenames_charttypes.hxx> +#include <com/sun/star/chart2/XChartTypeContainer.hpp> +#include <com/sun/star/chart2/XDataSeriesContainer.hpp> +#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <PropertyHelper.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <tools/diagnose_ex.h> + +#include <vector> +#include <algorithm> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::Property; + +namespace +{ + +enum +{ + PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME, + PROP_STOCKCHARTTYPE_TEMPLATE_OPEN, + PROP_STOCKCHARTTYPE_TEMPLATE_LOW_HIGH, + PROP_STOCKCHARTTYPE_TEMPLATE_JAPANESE +}; + +void lcl_AddPropertiesToVector( + std::vector< Property > & rOutProperties ) +{ + rOutProperties.emplace_back( "Volume", + PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "Open", + PROP_STOCKCHARTTYPE_TEMPLATE_OPEN, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "LowHigh", + PROP_STOCKCHARTTYPE_TEMPLATE_LOW_HIGH, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + rOutProperties.emplace_back( "Japanese", + PROP_STOCKCHARTTYPE_TEMPLATE_JAPANESE, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); +} + +struct StaticStockChartTypeTemplateDefaults_Initializer +{ + ::chart::tPropertyValueMap* operator()() + { + static ::chart::tPropertyValueMap aStaticDefaults; + lcl_AddDefaultsToMap( aStaticDefaults ); + return &aStaticDefaults; + } +private: + static void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) + { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME, false ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_STOCKCHARTTYPE_TEMPLATE_OPEN, false ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_STOCKCHARTTYPE_TEMPLATE_LOW_HIGH, true ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_STOCKCHARTTYPE_TEMPLATE_JAPANESE, false ); + } +}; + +struct StaticStockChartTypeTemplateDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticStockChartTypeTemplateDefaults_Initializer > +{ +}; + +struct StaticStockChartTypeTemplateInfoHelper_Initializer +{ + ::cppu::OPropertyArrayHelper* operator()() + { + static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); + return &aPropHelper; + } + +private: + static Sequence< Property > lcl_GetPropertySequence() + { + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + } +}; + +struct StaticStockChartTypeTemplateInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticStockChartTypeTemplateInfoHelper_Initializer > +{ +}; + +struct StaticStockChartTypeTemplateInfo_Initializer +{ + uno::Reference< beans::XPropertySetInfo >* operator()() + { + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticStockChartTypeTemplateInfoHelper::get() ) ); + return &xPropertySetInfo; + } +}; + +struct StaticStockChartTypeTemplateInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticStockChartTypeTemplateInfo_Initializer > +{ +}; + +} // anonymous namespace + +namespace chart +{ + +StockChartTypeTemplate::StockChartTypeTemplate( + uno::Reference< + uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StockVariant eVariant, + bool bJapaneseStyle ) : + ChartTypeTemplate( xContext, rServiceName ), + ::property::OPropertySet( m_aMutex ), + m_eStockVariant( eVariant ) +{ + setFastPropertyValue_NoBroadcast( + PROP_STOCKCHARTTYPE_TEMPLATE_OPEN, + uno::Any( ( eVariant == StockVariant::Open || + eVariant == StockVariant::VolumeOpen ))); + setFastPropertyValue_NoBroadcast( + PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME, + uno::Any( ( eVariant == StockVariant::Volume || + eVariant == StockVariant::VolumeOpen ))); + setFastPropertyValue_NoBroadcast( + PROP_STOCKCHARTTYPE_TEMPLATE_JAPANESE, + uno::Any( bJapaneseStyle )); +} + +StockChartTypeTemplate::~StockChartTypeTemplate() +{} +// ____ OPropertySet ____ +uno::Any StockChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticStockChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + return uno::Any(); + return (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL StockChartTypeTemplate::getInfoHelper() +{ + return *StaticStockChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL StockChartTypeTemplate::getPropertySetInfo() +{ + return *StaticStockChartTypeTemplateInfo::get(); +} + +sal_Int32 StockChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension ) +{ + // one x-axis + if( nDimension <= 0 ) + return 1; + // no further axes + if( nDimension >= 2 ) + return 0; + + // one or two y-axes depending on volume + OSL_ASSERT( nDimension == 1 ); + bool bHasVolume = false; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME ) >>= bHasVolume; + return bHasVolume ? 2 : 1; +} + +void SAL_CALL StockChartTypeTemplate::applyStyle( + const Reference< chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + try + { + sal_Int32 nNewAxisIndex = 0; + + bool bHasVolume = false; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME ) >>= bHasVolume; + if( bHasVolume && nChartTypeIndex != 0 ) + nNewAxisIndex = 1; + + Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY ); + if( xProp.is() ) + xProp->setPropertyValue( "AttachedAxisIndex", uno::Any( nNewAxisIndex ) ); + + if( bHasVolume && nChartTypeIndex==0 ) + { + //switch lines off for volume bars + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); + } + else + { + //ensure that lines are on + if( xProp.is() ) + { + drawing::LineStyle eStyle = drawing::LineStyle_NONE; + xProp->getPropertyValue( "LineStyle" ) >>= eStyle; + if( eStyle == drawing::LineStyle_NONE ) + xProp->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_SOLID )); + } + } + + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void SAL_CALL StockChartTypeTemplate::resetStyles( + const Reference< chart2::XDiagram >& xDiagram ) +{ + ChartTypeTemplate::resetStyles( xDiagram ); + if( getDimension() == 3 ) + { + std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + for (auto const& series : aSeriesVec) + { + Reference< beans::XPropertySet > xProp(series, uno::UNO_QUERY); + if( xProp.is() ) + xProp->setPropertyValue( "AttachedAxisIndex", uno::Any( sal_Int32(0) ) ); + } + } + + DiagramHelper::setVertical( xDiagram, false ); +} + +Reference< XChartType > StockChartTypeTemplate::getChartTypeForIndex( sal_Int32 nChartTypeIndex ) +{ + Reference< XChartType > xCT; + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY ); + if(xFact.is()) + { + bool bHasVolume = false; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME ) >>= bHasVolume; + if( bHasVolume ) + { + if( nChartTypeIndex == 0 ) + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ), uno::UNO_QUERY ); + else if( nChartTypeIndex == 1 ) + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ), uno::UNO_QUERY ); + else + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY ); + } + else + { + if( nChartTypeIndex == 0 ) + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ), uno::UNO_QUERY ); + else + xCT.set( xFact->createInstance( CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY ); + } + } + return xCT; +} + +void StockChartTypeTemplate::createChartTypes( + const Sequence< Sequence< Reference< XDataSeries > > > & aSeriesSeq, + const Sequence< Reference< XCoordinateSystem > > & rCoordSys, + const Sequence< Reference< XChartType > >& /* aOldChartTypesSeq */ ) +{ + if( !rCoordSys.hasElements() ) + return; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + bool bHasVolume = false; + bool bShowFirst = false; + bool bJapaneseStyle = false; + bool bShowHighLow = true; + + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME ) >>= bHasVolume; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_OPEN ) >>= bShowFirst; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_JAPANESE ) >>= bJapaneseStyle; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_LOW_HIGH ) >>= bShowHighLow; + + sal_Int32 nSeriesIndex = 0; + + std::vector< Reference< chart2::XChartType > > aChartTypeVec; + // Bars (Volume) + if( bHasVolume ) + { + // chart type + Reference< XChartType > xCT( + xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ), uno::UNO_QUERY_THROW ); + aChartTypeVec.push_back( xCT ); + + if( aSeriesSeq.getLength() > nSeriesIndex && + aSeriesSeq[nSeriesIndex].hasElements() ) + { + Reference< XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + xDSCnt->setDataSeries( aSeriesSeq[ nSeriesIndex ] ); + } + ++nSeriesIndex; + } + + Reference< XChartType > xCT( + xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ), uno::UNO_QUERY_THROW ); + aChartTypeVec.push_back( xCT ); + + Reference< beans::XPropertySet > xCTProp( xCT, uno::UNO_QUERY ); + if( xCTProp.is()) + { + xCTProp->setPropertyValue( "Japanese", uno::Any( bJapaneseStyle )); + xCTProp->setPropertyValue( "ShowFirst", uno::Any( bShowFirst )); + xCTProp->setPropertyValue( "ShowHighLow", uno::Any( bShowHighLow )); + } + + if( aSeriesSeq.getLength() > nSeriesIndex && + aSeriesSeq[ nSeriesIndex ].hasElements() ) + { + Reference< XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + xDSCnt->setDataSeries( aSeriesSeq[ nSeriesIndex ] ); + } + ++nSeriesIndex; + + // Lines (remaining series) + if( aSeriesSeq.getLength() > nSeriesIndex && + aSeriesSeq[ nSeriesIndex ].hasElements() ) + { + xCT.set( + xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW ); + aChartTypeVec.push_back( xCT ); + + Reference< XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW ); + xDSCnt->setDataSeries( aSeriesSeq[ nSeriesIndex ] ); + } + + Reference< XChartTypeContainer > xCTCnt( rCoordSys[ 0 ], uno::UNO_QUERY_THROW ); + xCTCnt->setChartTypes( comphelper::containerToSequence(aChartTypeVec) ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL StockChartTypeTemplate::matchesTemplate( + const uno::Reference< XDiagram >& xDiagram, + sal_Bool /* bAdaptProperties */ ) +{ + bool bResult = false; + + if( ! xDiagram.is()) + return bResult; + + try + { + bool bHasVolume = false, bHasOpenValue = false, bHasJapaneseStyle = false; + + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME ) >>= bHasVolume; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_OPEN ) >>= bHasOpenValue; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_JAPANESE ) >>= bHasJapaneseStyle; + + Reference< chart2::XChartType > xVolumeChartType; + Reference< chart2::XChartType > xCandleStickChartType; + Reference< chart2::XChartType > xLineChartType; + sal_Int32 nNumberOfChartTypes = 0; + + Reference< XCoordinateSystemContainer > xCooSysCnt( + xDiagram, uno::UNO_QUERY_THROW ); + const Sequence< Reference< XCoordinateSystem > > aCooSysSeq( + xCooSysCnt->getCoordinateSystems()); + for( Reference< XCoordinateSystem > const & coords : aCooSysSeq ) + { + Reference< XChartTypeContainer > xCTCnt( coords, uno::UNO_QUERY_THROW ); + const Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes()); + for( Reference< XChartType > const & chartType : aChartTypeSeq ) + { + if( chartType.is()) + { + ++nNumberOfChartTypes; + if( nNumberOfChartTypes > 3 ) + break; + OUString aCTService = chartType->getChartType(); + if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ) + xVolumeChartType.set( chartType ); + else if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ) + xCandleStickChartType.set( chartType ); + else if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_LINE ) + xLineChartType.set( chartType ); + } + } + if( nNumberOfChartTypes > 3 ) + break; + } + + if (xCandleStickChartType.is() && bHasVolume == xVolumeChartType.is()) + { + bResult = true; + + // check for japanese style + Reference< beans::XPropertySet > xCTProp( xCandleStickChartType, uno::UNO_QUERY ); + if( xCTProp.is()) + { + bool bJapaneseProp = false; + xCTProp->getPropertyValue( "Japanese") >>= bJapaneseProp; + bResult = bResult && ( bHasJapaneseStyle == bJapaneseProp ); + + // in old chart japanese == showFirst + bool bShowFirstProp = false; + xCTProp->getPropertyValue( "ShowFirst") >>= bShowFirstProp; + bResult = bResult && ( bHasOpenValue == bShowFirstProp ); + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return bResult; +} + +Reference< XChartType > SAL_CALL StockChartTypeTemplate::getChartTypeForNewSeries( + const uno::Sequence< Reference< chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + Reference< chart2::XChartType > xResult; + + try + { + Reference< lang::XMultiServiceFactory > xFact( + GetComponentContext()->getServiceManager(), uno::UNO_QUERY_THROW ); + xResult.set( xFact->createInstance( + CHART2_SERVICE_NAME_CHARTTYPE_LINE ), uno::UNO_QUERY_THROW ); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +Reference< XDataInterpreter > SAL_CALL StockChartTypeTemplate::getDataInterpreter() +{ + if( ! m_xDataInterpreter.is()) + m_xDataInterpreter.set( new StockDataInterpreter( m_eStockVariant ) ); + + return m_xDataInterpreter; +} + +IMPLEMENT_FORWARD_XINTERFACE2( StockChartTypeTemplate, ChartTypeTemplate, OPropertySet ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( StockChartTypeTemplate, ChartTypeTemplate, OPropertySet ) + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/StockChartTypeTemplate.hxx b/chart2/source/model/template/StockChartTypeTemplate.hxx new file mode 100644 index 000000000..6a05450f8 --- /dev/null +++ b/chart2/source/model/template/StockChartTypeTemplate.hxx @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_STOCKCHARTTYPETEMPLATE_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_STOCKCHARTTYPETEMPLATE_HXX + +#include "ChartTypeTemplate.hxx" +#include <OPropertySet.hxx> +#include <MutexContainer.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class StockChartTypeTemplate : + public MutexContainer, + public ChartTypeTemplate, + public ::property::OPropertySet +{ +public: + enum class StockVariant + { + NONE, + Open, + Volume, + VolumeOpen + }; + + /** CTOR + + @param bJapaneseStyle + If true, the candlesticks are drawn as solid white or black boxes + depending on rising or falling stock-values. Otherwise the + open-value will be drawn as a small line at the left side of a + straight vertical line, and the close-value on the right hand side. + */ + explicit StockChartTypeTemplate( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + const OUString & rServiceName, + StockVariant eVariant, + bool bJapaneseStyle ); + virtual ~StockChartTypeTemplate() override; + + /// merge XInterface implementations + DECLARE_XINTERFACE() + /// merge XTypeProvider implementations + DECLARE_XTYPEPROVIDER() + +protected: + // ____ OPropertySet ____ + virtual css::uno::Any GetDefaultValue( sal_Int32 nHandle ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual sal_Bool SAL_CALL matchesTemplate( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) override; + virtual css::uno::Reference< css::chart2::XChartType > SAL_CALL + getChartTypeForNewSeries( const css::uno::Sequence< + css::uno::Reference< + css::chart2::XChartType > >& aFormerlyUsedChartTypes ) override; + virtual css::uno::Reference< css::chart2::XDataInterpreter > SAL_CALL getDataInterpreter() override; + virtual void SAL_CALL applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void SAL_CALL resetStyles( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) override; + + // ChartTypeTemplate + virtual sal_Int32 getAxisCountByDimension( sal_Int32 nDimension ) override; + + // ____ ChartTypeTemplate ____ + virtual void createChartTypes( + const css::uno::Sequence< + css::uno::Sequence< + css::uno::Reference< + css::chart2::XDataSeries > > >& aSeriesSeq, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XCoordinateSystem > > & rCoordSys, + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XChartType > > & aOldChartTypesSeq + ) override; + + virtual css::uno::Reference< css::chart2::XChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + +private: + // todo: deprecate this variable + StockVariant m_eStockVariant; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_STOCKCHARTTYPETEMPLATE_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/StockDataInterpreter.cxx b/chart2/source/model/template/StockDataInterpreter.cxx new file mode 100644 index 000000000..15c289197 --- /dev/null +++ b/chart2/source/model/template/StockDataInterpreter.cxx @@ -0,0 +1,319 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "StockDataInterpreter.hxx" +#include <DataSeries.hxx> +#include <com/sun/star/chart2/data/XDataSink.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using namespace ::std; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +namespace chart +{ + +// explicit +StockDataInterpreter::StockDataInterpreter( + StockChartTypeTemplate::StockVariant eVariant ) : + DataInterpreter(), + m_eStockVariant( eVariant ) +{} + +StockDataInterpreter::~StockDataInterpreter() +{} + +// ____ XDataInterpreter ____ +InterpretedData SAL_CALL StockDataInterpreter::interpretDataSource( + const Reference< data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& rArguments, + const Sequence< Reference< XDataSeries > >& rSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + + Reference< data::XLabeledDataSequence > xCategories; + Sequence< Reference< data::XLabeledDataSequence > > aData( xSource->getDataSequences() ); + const sal_Int32 nDataCount( aData.getLength()); + + // sub-type properties + const StockChartTypeTemplate::StockVariant eVar( GetStockVariant()); + const bool bHasOpenValues (( eVar == StockChartTypeTemplate::StockVariant::Open ) || + ( eVar == StockChartTypeTemplate::StockVariant::VolumeOpen )); + const bool bHasVolume (( eVar == StockChartTypeTemplate::StockVariant::Volume ) || + ( eVar == StockChartTypeTemplate::StockVariant::VolumeOpen )); + const bool bHasCategories( HasCategories( rArguments, aData )); + + // necessary roles for "full series" + // low/high/close + sal_Int32 nNumberOfNecessarySequences( 3 ); + if( bHasOpenValues ) + ++nNumberOfNecessarySequences; + if( bHasVolume ) + ++nNumberOfNecessarySequences; + + // calculate number of full series (nNumOfFullSeries) and the number of remaining + // sequences used for additional "incomplete series" (nRemaining) + sal_Int32 nNumOfFullSeries( 0 ); + sal_Int32 nRemaining( 0 ); + { + sal_Int32 nAvailableSequences( nDataCount ); + if( bHasCategories ) + --nAvailableSequences; + nNumOfFullSeries = nAvailableSequences / nNumberOfNecessarySequences; + nRemaining = nAvailableSequences % nNumberOfNecessarySequences; + } + sal_Int32 nCandleStickSeries = nNumOfFullSeries; + sal_Int32 nVolumeSeries = nNumOfFullSeries; + + sal_Int32 nNumberOfGroups( bHasVolume ? 2 : 1 ); + // sequences of data::XLabeledDataSequence per series per group + Sequence< Sequence< Sequence< Reference< data::XLabeledDataSequence > > > > aSequences( nNumberOfGroups ); + sal_Int32 nBarGroupIndex( 0 ); + sal_Int32 nCandleStickGroupIndex( nNumberOfGroups - 1 ); + + // allocate space for labeled sequences + if( nRemaining > 0 ) + ++nCandleStickSeries; + aSequences[nCandleStickGroupIndex].realloc( nCandleStickSeries ); + if( bHasVolume ) + { + // if there are remaining sequences, the first one is taken for + // additional close values, the second one is taken as volume, if volume + // is used + if( nRemaining > 1 ) + ++nVolumeSeries; + aSequences[nBarGroupIndex].realloc( nVolumeSeries ); + } + + // create data + sal_Int32 nSourceIndex = 0; // index into aData sequence + + // 1. categories + if( bHasCategories ) + { + xCategories.set( aData[nSourceIndex] ); + ++nSourceIndex; + } + + // 2. create "full" series + for( sal_Int32 nLabeledSeqIdx=0; nLabeledSeqIdx<nNumOfFullSeries; ++nLabeledSeqIdx ) + { + // bar + if( bHasVolume ) + { + aSequences[nBarGroupIndex][nLabeledSeqIdx].realloc( 1 ); + aSequences[nBarGroupIndex][nLabeledSeqIdx][0].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-y"); + ++nSourceIndex; + } + + sal_Int32 nSeqIdx = 0; + if( bHasOpenValues ) + { + aSequences[nCandleStickGroupIndex][nLabeledSeqIdx].realloc( 4 ); + aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-first"); + ++nSourceIndex; + ++nSeqIdx; + } + else + aSequences[nCandleStickGroupIndex][nLabeledSeqIdx].realloc( 3 ); + + aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-min"); + ++nSourceIndex; + ++nSeqIdx; + + aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-max"); + ++nSourceIndex; + ++nSeqIdx; + + aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-last"); + ++nSourceIndex; + ++nSeqIdx; + } + + // 3. create series with remaining sequences + if( bHasVolume && nRemaining > 1 ) + { + OSL_ASSERT( nVolumeSeries > nNumOfFullSeries ); + aSequences[nBarGroupIndex][nVolumeSeries - 1].realloc( 1 ); + OSL_ASSERT( nDataCount > nSourceIndex ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-y"); + aSequences[nBarGroupIndex][nVolumeSeries - 1][0].set( aData[nSourceIndex] ); + ++nSourceIndex; + --nRemaining; + OSL_ENSURE( nRemaining, "additional bar should only be used if there is at least one more sequence for a candle stick" ); + } + + // candle-stick + if( nRemaining > 0 ) + { + OSL_ASSERT( nCandleStickSeries > nNumOfFullSeries ); + const sal_Int32 nSeriesIndex = nCandleStickSeries - 1; + aSequences[nCandleStickGroupIndex][nSeriesIndex].realloc( nRemaining ); + OSL_ASSERT( nDataCount > nSourceIndex ); + + // 1. low + sal_Int32 nSeqIdx( 0 ); + aSequences[nCandleStickGroupIndex][nSeriesIndex][nSeqIdx].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-min"); + ++nSourceIndex; + ++nSeqIdx; + + // 2. high + if( nSeqIdx < nRemaining ) + { + aSequences[nCandleStickGroupIndex][nSeriesIndex][nSeqIdx].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-max"); + ++nSourceIndex; + ++nSeqIdx; + } + + // 3. close + OSL_ENSURE( bHasOpenValues || nSeqIdx >= nRemaining, "could have created full series" ); + if( nSeqIdx < nRemaining ) + { + aSequences[nCandleStickGroupIndex][nSeriesIndex][nSeqIdx].set( aData[nSourceIndex] ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-last"); + ++nSourceIndex; + ++nSeqIdx; + } + + // 4. open + OSL_ENSURE( nSeqIdx >= nRemaining, "could have created full series" ); + } + + // create DataSeries + Sequence< Sequence< Reference< XDataSeries > > > aResultSeries( nNumberOfGroups ); + sal_Int32 nGroupIndex, nReUsedSeriesIdx = 0; + for( nGroupIndex=0; nGroupIndex<nNumberOfGroups; ++nGroupIndex ) + { + const sal_Int32 nNumSeriesData = aSequences[nGroupIndex].getLength(); + aResultSeries[nGroupIndex].realloc( nNumSeriesData ); + for( sal_Int32 nSeriesIdx = 0; nSeriesIdx < nNumSeriesData; ++nSeriesIdx, ++nReUsedSeriesIdx ) + { + try + { + Reference< XDataSeries > xSeries; + if( nReUsedSeriesIdx < rSeriesToReUse.getLength()) + xSeries.set( rSeriesToReUse[nReUsedSeriesIdx] ); + else + xSeries.set( new DataSeries ); + OSL_ASSERT( xSeries.is() ); + Reference< data::XDataSink > xSink( xSeries, uno::UNO_QUERY_THROW ); + xSink->setData( aSequences[nGroupIndex][nSeriesIdx] ); + aResultSeries[nGroupIndex][nSeriesIdx].set( xSeries ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + + return InterpretedData( aResultSeries, xCategories ); +} + +// criterion: there must be two groups for stock-charts with volume and all +// series must have the correct number of data::XLabeledDataSequences + +// todo: skip first criterion? (to allow easy switch from stock-chart without +// volume to one with volume) +sal_Bool SAL_CALL StockDataInterpreter::isDataCompatible( + const InterpretedData& aInterpretedData ) +{ + // high/low/close + sal_Int32 nNumberOfNecessarySequences = 3; + // open + StockChartTypeTemplate::StockVariant eVar( GetStockVariant()); + if( ( eVar == StockChartTypeTemplate::StockVariant::Open ) || + ( eVar == StockChartTypeTemplate::StockVariant::VolumeOpen )) + ++nNumberOfNecessarySequences; + // volume + bool bHasVolume = (( eVar == StockChartTypeTemplate::StockVariant::Volume ) || + ( eVar == StockChartTypeTemplate::StockVariant::VolumeOpen )); + + // 1. correct number of sub-types + if( aInterpretedData.Series.getLength() < (bHasVolume ? 2 : 1 )) + return false; + + // 2. a. volume -- use default check + if( bHasVolume ) + { + if( ! DataInterpreter::isDataCompatible( + InterpretedData( Sequence< Sequence< Reference< XDataSeries > > >( + aInterpretedData.Series.getConstArray(), 1 ), + aInterpretedData.Categories ))) + return false; + } + + // 2. b. candlestick + { + OSL_ASSERT( aInterpretedData.Series.getLength() > (bHasVolume ? 1 : 0)); + const Sequence< Reference< XDataSeries > > aSeries( aInterpretedData.Series[(bHasVolume ? 1 : 0)] ); + if(!aSeries.hasElements()) + return false; + for( Reference< XDataSeries > const & dataSeries : aSeries ) + { + try + { + Reference< data::XDataSource > xSrc( dataSeries, uno::UNO_QUERY_THROW ); + Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSrc->getDataSequences()); + if( aSeq.getLength() != nNumberOfNecessarySequences ) + return false; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + + // 2. c. additional series + // ignore + + return true; +} + +InterpretedData SAL_CALL StockDataInterpreter::reinterpretDataSeries( + const InterpretedData& aInterpretedData ) +{ + // prerequisite: StockDataInterpreter::isDataCompatible() returned true + return aInterpretedData; +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/StockDataInterpreter.hxx b/chart2/source/model/template/StockDataInterpreter.hxx new file mode 100644 index 000000000..2bd5b2b61 --- /dev/null +++ b/chart2/source/model/template/StockDataInterpreter.hxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_STOCKDATAINTERPRETER_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_STOCKDATAINTERPRETER_HXX + +#include "DataInterpreter.hxx" + +#include "StockChartTypeTemplate.hxx" + +namespace chart +{ + +class StockDataInterpreter : public DataInterpreter +{ +public: + explicit StockDataInterpreter( + StockChartTypeTemplate::StockVariant eVariant ); + virtual ~StockDataInterpreter() override; + +protected: + // ____ XDataInterpreter ____ + virtual css::chart2::InterpretedData SAL_CALL interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const css::uno::Sequence< css::uno::Reference< css::chart2::XDataSeries > >& aSeriesToReUse ) override; + virtual sal_Bool SAL_CALL isDataCompatible( + const css::chart2::InterpretedData& aInterpretedData ) override; + virtual css::chart2::InterpretedData SAL_CALL reinterpretDataSeries( + const css::chart2::InterpretedData& aInterpretedData ) override; + +private: + StockChartTypeTemplate::StockVariant m_eStockVariant; + + StockChartTypeTemplate::StockVariant GetStockVariant() const { return m_eStockVariant;} +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_STOCKDATAINTERPRETER_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/XYDataInterpreter.cxx b/chart2/source/model/template/XYDataInterpreter.cxx new file mode 100644 index 000000000..a3fb67fa9 --- /dev/null +++ b/chart2/source/model/template/XYDataInterpreter.cxx @@ -0,0 +1,252 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "XYDataInterpreter.hxx" +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <CommonConverters.hxx> +#include <com/sun/star/chart2/data/XDataSink.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <tools/diagnose_ex.h> +#include <sal/log.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using namespace ::std; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +namespace chart +{ + +XYDataInterpreter::XYDataInterpreter() : + DataInterpreter() +{ +} + +XYDataInterpreter::~XYDataInterpreter() +{ +} + +// ____ XDataInterpreter ____ +chart2::InterpretedData SAL_CALL XYDataInterpreter::interpretDataSource( + const Reference< chart2::data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const Sequence< Reference< XDataSeries > >& aSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + + const Sequence< Reference< data::XLabeledDataSequence > > aData( xSource->getDataSequences() ); + + Reference< data::XLabeledDataSequence > xValuesX; + vector< Reference< data::XLabeledDataSequence > > aSequencesVec; + + Reference< data::XLabeledDataSequence > xCategories; + bool bHasCategories = HasCategories( aArguments, aData ); + bool bUseCategoriesAsX = UseCategoriesAsX( aArguments ); + + // parse data + bool bCategoriesUsed = false; + bool bSetXValues = aData.getLength()>1; + for( Reference< data::XLabeledDataSequence > const & labelData : aData ) + { + try + { + if( bHasCategories && ! bCategoriesUsed ) + { + xCategories.set( labelData ); + if( xCategories.is()) + { + SetRole( xCategories->getValues(), "categories"); + if( bUseCategoriesAsX ) + bSetXValues = false; + } + bCategoriesUsed = true; + } + else if( !xValuesX.is() && bSetXValues ) + { + xValuesX.set( labelData ); + if( xValuesX.is()) + SetRole( xValuesX->getValues(), "values-x"); + } + else + { + aSequencesVec.push_back( labelData ); + if( labelData.is()) + SetRole( labelData->getValues(), "values-y"); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + // create DataSeries + vector< Reference< XDataSeries > > aSeriesVec; + aSeriesVec.reserve( aSequencesVec.size()); + + Reference< data::XLabeledDataSequence > xClonedXValues = xValuesX; + Reference< util::XCloneable > xCloneable( xValuesX, uno::UNO_QUERY ); + + sal_Int32 nSeriesIndex = 0; + for (auto const& elem : aSequencesVec) + { + vector< Reference< data::XLabeledDataSequence > > aNewData; + + if( nSeriesIndex && xCloneable.is() ) + xClonedXValues.set( xCloneable->createClone(), uno::UNO_QUERY ); + if( xValuesX.is() ) + aNewData.push_back( xClonedXValues ); + + aNewData.push_back(elem); + + Reference< XDataSeries > xSeries; + if( nSeriesIndex < aSeriesToReUse.getLength()) + xSeries.set( aSeriesToReUse[nSeriesIndex] ); + else + xSeries.set( new DataSeries ); + OSL_ASSERT( xSeries.is() ); + Reference< data::XDataSink > xSink( xSeries, uno::UNO_QUERY ); + OSL_ASSERT( xSink.is() ); + xSink->setData( comphelper::containerToSequence( aNewData ) ); + + aSeriesVec.push_back( xSeries ); + ++nSeriesIndex; + } + + Sequence< Sequence< Reference< XDataSeries > > > aSeries(1); + aSeries[0] = comphelper::containerToSequence( aSeriesVec ); + return InterpretedData( aSeries, xCategories ); +} + +chart2::InterpretedData SAL_CALL XYDataInterpreter::reinterpretDataSeries( + const chart2::InterpretedData& aInterpretedData ) +{ + InterpretedData aResult( aInterpretedData ); + + sal_Int32 i=0; + Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + const sal_Int32 nCount = aSeries.getLength(); + for( ; i<nCount; ++i ) + { + try + { + Reference< data::XDataSource > xSeriesSource( aSeries[i], uno::UNO_QUERY_THROW ); + Sequence< Reference< data::XLabeledDataSequence > > aNewSequences; + + // values-y + Reference< data::XLabeledDataSequence > xValuesY( + DataSeriesHelper::getDataSequenceByRole( xSeriesSource, "values-y" )); + Reference< data::XLabeledDataSequence > xValuesX( + DataSeriesHelper::getDataSequenceByRole( xSeriesSource, "values-x" )); + // re-use values-... as values-x/values-y + if( ! xValuesX.is() || + ! xValuesY.is()) + { + vector< Reference< data::XLabeledDataSequence > > aValueSeqVec( + DataSeriesHelper::getAllDataSequencesByRole( + xSeriesSource->getDataSequences(), "values" )); + if( xValuesX.is()) + aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesX )); + if( xValuesY.is()) + aValueSeqVec.erase( find( aValueSeqVec.begin(), aValueSeqVec.end(), xValuesY )); + + size_t nIndex = 0; + if( ! xValuesY.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesY.set( aValueSeqVec[nIndex++] ); + if( xValuesY.is()) + SetRole( xValuesY->getValues(), "values-y"); + } + + if( ! xValuesX.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesX.set( aValueSeqVec[nIndex++] ); + if( xValuesX.is()) + SetRole( xValuesY->getValues(), "values-x"); + } + } + if( xValuesY.is()) + { + if( xValuesX.is()) + { + aNewSequences.realloc(2); + aNewSequences[0] = xValuesX; + aNewSequences[1] = xValuesY; + } + else + { + aNewSequences.realloc(1); + aNewSequences[0] = xValuesY; + } + } + + const Sequence< Reference< data::XLabeledDataSequence > > aSeqs( xSeriesSource->getDataSequences()); + if( aSeqs.getLength() != aNewSequences.getLength() ) + { +#ifdef DBG_UTIL + for( auto const & j : aSeqs ) + { + SAL_WARN_IF((j == xValuesY || j == xValuesX), "chart2.template", "All sequences should be used" ); + } +#endif + Reference< data::XDataSink > xSink( xSeriesSource, uno::UNO_QUERY_THROW ); + xSink->setData( aNewSequences ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return aResult; +} + +// criterion: all series must have exactly two data::XLabeledDataSequences +sal_Bool SAL_CALL XYDataInterpreter::isDataCompatible( + const chart2::InterpretedData& aInterpretedData ) +{ + const Sequence< Reference< XDataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + for( Reference< XDataSeries > const & dataSeries : aSeries ) + { + try + { + Reference< data::XDataSource > xSrc( dataSeries, uno::UNO_QUERY_THROW ); + Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSrc->getDataSequences()); + if( aSeq.getLength() != 2 ) + return false; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return true; +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/model/template/XYDataInterpreter.hxx b/chart2/source/model/template/XYDataInterpreter.hxx new file mode 100644 index 000000000..c57889ce8 --- /dev/null +++ b/chart2/source/model/template/XYDataInterpreter.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_XYDATAINTERPRETER_HXX +#define INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_XYDATAINTERPRETER_HXX + +#include "DataInterpreter.hxx" + +namespace chart +{ + +class XYDataInterpreter : public DataInterpreter +{ +public: + explicit XYDataInterpreter(); + virtual ~XYDataInterpreter() override; + +protected: + // ____ XDataInterpreter ____ + virtual css::chart2::InterpretedData SAL_CALL interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const css::uno::Sequence< css::uno::Reference< css::chart2::XDataSeries > >& aSeriesToReUse ) override; + virtual css::chart2::InterpretedData SAL_CALL reinterpretDataSeries( + const css::chart2::InterpretedData& aInterpretedData ) override; + virtual sal_Bool SAL_CALL isDataCompatible( + const css::chart2::InterpretedData& aInterpretedData ) override; +}; + +} // namespace chart + +// INCLUDED_CHART2_SOURCE_MODEL_TEMPLATE_XYDATAINTERPRETER_HXX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |