diff options
Diffstat (limited to 'chart2/source/model/template')
50 files changed, 9553 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..b0581ddc8 --- /dev/null +++ b/chart2/source/model/template/AreaChartType.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 "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 )); +} + +rtl::Reference< ChartType > AreaChartType::cloneChartType() const +{ + return 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..8ca01e1f3 --- /dev/null +++ b/chart2/source/model/template/AreaChartType.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const 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 + +/* 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..32df26a18 --- /dev/null +++ b/chart2/source/model/template/AreaChartTypeTemplate.cxx @@ -0,0 +1,221 @@ +/* -*- 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 "AreaChartType.hxx" +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <DataSeries.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 <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 ____ +void AreaChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticAreaChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*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; +} + +// ____ ChartTypeTemplate ____ +void AreaChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); +} + +void AreaChartTypeTemplate::resetStyles2( const rtl::Reference< ::chart::Diagram >& xDiagram ) +{ + ChartTypeTemplate::resetStyles2( xDiagram ); + std::vector< rtl::Reference< ::chart::DataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + uno::Any aLineStyleAny( drawing::LineStyle_NONE ); + for (auto const& series : aSeriesVec) + { + if( series->getPropertyValue( "BorderStyle") == aLineStyleAny ) + { + series->setPropertyToDefault( "BorderStyle"); + } + } +} + +rtl::Reference< ChartType > AreaChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + return new AreaChartType(); +} + +rtl::Reference< ChartType > AreaChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > 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..3116c0d59 --- /dev/null +++ b/chart2/source/model/template/AreaChartTypeTemplate.hxx @@ -0,0 +1,82 @@ +/* -*- 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 . + */ +#pragma once + +#include <ChartTypeTemplate.hxx> +#include <StackMode.hxx> + +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class AreaChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ ChartTypeTemplate ____ + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void resetStyles2( + const rtl::Reference< ::chart::Diagram >& xDiagram ) override; + + // ____ ChartTypeTemplate ____ + virtual rtl::Reference< ::chart::ChartType > + 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 + +/* 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..2a94db82b --- /dev/null +++ b/chart2/source/model/template/BarChartType.cxx @@ -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 . + */ + +#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 )); +} + +rtl::Reference< ChartType > BarChartType::cloneChartType() const +{ + return new BarChartType( *this ); +} + +// ____ XChartType ____ +OUString SAL_CALL BarChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_BAR; +} + +uno::Sequence< OUString > BarChartType::getSupportedPropertyRoles() +{ + return { "FillColor", "BorderColor" }; +} + +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..cceaf0577 --- /dev/null +++ b/chart2/source/model/template/BarChartType.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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const 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 + +/* 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..0c3ca6566 --- /dev/null +++ b/chart2/source/model/template/BarChartTypeTemplate.cxx @@ -0,0 +1,292 @@ +/* -*- 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 "ColumnChartType.hxx" +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <DataSeries.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/uno/XComponentContext.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); +} + +// ____ ChartTypeTemplate ____ +bool BarChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate2( 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; +} + +rtl::Reference< ChartType > BarChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + return new ColumnChartType(); +} + +rtl::Reference< ChartType > BarChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > xResult( getChartTypeForIndex( 0 ) ); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + return xResult; +} + +// ____ OPropertySet ____ +void BarChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticBarChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL BarChartTypeTemplate::getInfoHelper() +{ + return *StaticBarChartTypeTemplateInfoHelper::get(); +} + +// ____ XPropertySet ____ +Reference< beans::XPropertySetInfo > SAL_CALL BarChartTypeTemplate::getPropertySetInfo() +{ + return *StaticBarChartTypeTemplateInfo::get(); +} + +void BarChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( 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 BarChartTypeTemplate::resetStyles2( + const rtl::Reference< ::chart::Diagram >& xDiagram ) +{ + ChartTypeTemplate::resetStyles2( xDiagram ); + std::vector< rtl::Reference< DataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + uno::Any aLineStyleAny( drawing::LineStyle_NONE ); + for (auto const& series : aSeriesVec) + { + if( getDimension() == 3 ) + series->setPropertyToDefault( "Geometry3D"); + if( series->getPropertyValue( "BorderStyle") == aLineStyleAny ) + { + series->setPropertyToDefault( "BorderStyle"); + } + } + + DiagramHelper::setVertical( xDiagram, false ); +} + +void BarChartTypeTemplate::createCoordinateSystems( + const rtl::Reference< ::chart::Diagram > & xDiagram ) +{ + ChartTypeTemplate::createCoordinateSystems( xDiagram ); + + 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..62188279e --- /dev/null +++ b/chart2/source/model/template/BarChartTypeTemplate.hxx @@ -0,0 +1,96 @@ +/* -*- 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 . + */ +#pragma once + +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> + +#include <ChartTypeTemplate.hxx> +#include <StackMode.hxx> + +namespace chart +{ + +class BarChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ ChartTypeTemplate ____ + virtual bool matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void resetStyles2( + const rtl::Reference< ::chart::Diagram >& xDiagram ) override; + virtual rtl::Reference< ::chart::ChartType > + 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 rtl::Reference< ::chart::Diagram > & xDiagram ) override; + +private: + StackMode m_eStackMode; + BarDirection m_eBarDirection; + sal_Int32 m_nDim; +}; + +} // namespace chart + +/* 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..3521f7909 --- /dev/null +++ b/chart2/source/model/template/BubbleChartType.cxx @@ -0,0 +1,219 @@ +/* -*- 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 <Axis.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 )); +} + +rtl::Reference< ChartType > BubbleChartType::cloneChartType() const +{ + return new BubbleChartType( *this ); +} + +// ____ XChartType ____ +rtl::Reference< ::chart::BaseCoordinateSystem > + BubbleChartType::createCoordinateSystem2( sal_Int32 DimensionCount ) +{ + rtl::Reference< CartesianCoordinateSystem > xResult = + new CartesianCoordinateSystem( DimensionCount ); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + rtl::Reference< Axis > xAxis = xResult->getAxisByDimension2( 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() +{ + return { "label", "values-x", "values-y", "values-size" }; +} + +uno::Sequence< OUString > SAL_CALL BubbleChartType::getSupportedPropertyRoles() +{ + return { "FillColor", "BorderColor" }; +} + +OUString SAL_CALL BubbleChartType::getRoleOfSequenceForSeriesLabel() +{ + return "values-size"; +} + +// ____ OPropertySet ____ +void BubbleChartType::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticBubbleChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*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..a2afa7e69 --- /dev/null +++ b/chart2/source/model/template/BubbleChartType.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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const 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 OUString SAL_CALL getRoleOfSequenceForSeriesLabel() override; + + // ____ OPropertySet ____ + virtual void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) 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; + + virtual rtl::Reference< ::chart::BaseCoordinateSystem > + createCoordinateSystem2( sal_Int32 DimensionCount ) override; +}; + +} // namespace chart + +/* 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..b09c9b9da --- /dev/null +++ b/chart2/source/model/template/BubbleChartTypeTemplate.cxx @@ -0,0 +1,195 @@ +/* -*- 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 "BubbleChartType.hxx" +#include "BubbleDataInterpreter.hxx" +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <PropertyHelper.hxx> +#include <com/sun/star/uno/XComponentContext.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 ____ +void BubbleChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticBubbleChartTypeTemplateDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*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 BubbleChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); +} + +// ____ XChartTypeTemplate ____ +sal_Bool SAL_CALL BubbleChartTypeTemplate::supportsCategories() +{ + return false; +} + +rtl::Reference< ChartType > BubbleChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + return new BubbleChartType(); +} + +rtl::Reference< ChartType > BubbleChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new BubbleChartType(); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +rtl::Reference< DataInterpreter > BubbleChartTypeTemplate::getDataInterpreter2() +{ + 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..f4e5c9b3c --- /dev/null +++ b/chart2/source/model/template/BubbleChartTypeTemplate.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 . + */ +#pragma once + +#include <ChartTypeTemplate.hxx> +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class BubbleChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ ChartTypeTemplate ____ + virtual sal_Bool SAL_CALL supportsCategories() override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual rtl::Reference< ::chart::DataInterpreter > getDataInterpreter2() override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + + // ____ ChartTypeTemplate ____ + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + virtual sal_Int32 getDimension() const override; + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; +}; + +} // namespace chart + +/* 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..7243b43aa --- /dev/null +++ b/chart2/source/model/template/BubbleDataInterpreter.cxx @@ -0,0 +1,278 @@ +/* -*- 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 <sal/config.h> + +#include <cstddef> + +#include "BubbleDataInterpreter.hxx" +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <CommonConverters.hxx> +#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() +{ +} + +BubbleDataInterpreter::~BubbleDataInterpreter() +{ +} + +// ____ XDataInterpreter ____ +InterpretedData BubbleDataInterpreter::interpretDataSource( + const Reference< chart2::data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const std::vector< rtl::Reference< DataSeries > >& aSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + + std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aData = DataInterpreter::getDataSequences(xSource); + + uno::Reference< chart2::data::XLabeledDataSequence > xValuesX; + vector< uno::Reference< chart2::data::XLabeledDataSequence > > aYValuesVector; + vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSizeValuesVector; + + uno::Reference< chart2::data::XLabeledDataSequence > xCategories; + bool bHasCategories = HasCategories( aArguments, aData ); + bool bUseCategoriesAsX = UseCategoriesAsX( aArguments ); + + sal_Int32 nDataSeqCount = aData.size(); + + 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 = aData[nDataIdx]; + if( xCategories.is()) + { + SetRole( xCategories->getValues(), "categories"); + if( bUseCategoriesAsX ) + { + bSetXValues = false; + bNextIsYValues = nDataSeqCount > 2; + } + } + bCategoriesUsed = true; + } + else if( !xValuesX.is() && bSetXValues ) + { + xValuesX = 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 + std::size_t nSeriesIndex = 0; + vector< rtl::Reference< DataSeries > > 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< uno::Reference< chart2::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]); + + rtl::Reference< DataSeries > xSeries; + if( nSeriesIndex < aSeriesToReUse.size()) + xSeries = aSeriesToReUse[nSeriesIndex]; + else + xSeries = new DataSeries; + assert( xSeries.is() ); + xSeries->setData( aNewData ); + + aSeriesVec.push_back( xSeries ); + } + + return { { aSeriesVec }, xCategories }; +} + +InterpretedData BubbleDataInterpreter::reinterpretDataSeries( + const InterpretedData& aInterpretedData ) +{ + InterpretedData aResult( aInterpretedData ); + + sal_Int32 i=0; + std::vector< rtl::Reference< DataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + const sal_Int32 nCount = aSeries.size(); + for( ; i<nCount; ++i ) + { + try + { + std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aNewSequences; + + uno::Reference< chart2::data::XLabeledDataSequence > xValuesSize( + DataSeriesHelper::getDataSequenceByRole( aSeries[i], "values-size" )); + uno::Reference< chart2::data::XLabeledDataSequence > xValuesY( + DataSeriesHelper::getDataSequenceByRole( aSeries[i], "values-y" )); + uno::Reference< chart2::data::XLabeledDataSequence > xValuesX( + DataSeriesHelper::getDataSequenceByRole( aSeries[i], "values-x" )); + + if( ! xValuesX.is() || + ! xValuesY.is() || + ! xValuesSize.is() ) + { + vector< uno::Reference< chart2::data::XLabeledDataSequence > > aValueSeqVec( + DataSeriesHelper::getAllDataSequencesByRole( + aSeries[i]->getDataSequences2(), "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 = aValueSeqVec[nIndex++]; + if( xValuesSize.is()) + SetRole( xValuesSize->getValues(), "values-size"); + } + + if( ! xValuesY.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesY = aValueSeqVec[nIndex++]; + if( xValuesY.is()) + SetRole( xValuesY->getValues(), "values-y"); + } + + if( ! xValuesX.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesX = aValueSeqVec[nIndex++]; + if( xValuesX.is()) + SetRole( xValuesY->getValues(), "values-x"); + } + } + if( xValuesSize.is()) + { + if( xValuesY.is() ) + { + if( xValuesX.is() ) + { + aNewSequences = { xValuesX, xValuesY, xValuesSize }; + } + else + { + aNewSequences = { xValuesY, xValuesSize }; + } + } + else + { + aNewSequences = { xValuesSize }; + } + } + + const std::vector< uno::Reference< data::XLabeledDataSequence > > & aSeqs = aSeries[i]->getDataSequences2(); + if( aSeqs.size() != aNewSequences.size() ) + { +#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 + aSeries[i]->setData( aNewSequences ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return aResult; +} + +bool BubbleDataInterpreter::isDataCompatible( + const InterpretedData& aInterpretedData ) +{ + const std::vector< rtl::Reference< DataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + for( rtl::Reference< DataSeries > const & dataSeries : aSeries ) + { + try + { + if( dataSeries->getDataSequences2().size() != 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..ff4b56de6 --- /dev/null +++ b/chart2/source/model/template/BubbleDataInterpreter.hxx @@ -0,0 +1,46 @@ +/* -*- 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 . + */ +#pragma once + +#include <DataInterpreter.hxx> + +namespace chart +{ + +class BubbleDataInterpreter : public DataInterpreter +{ +public: + explicit BubbleDataInterpreter(); + virtual ~BubbleDataInterpreter() override; + +protected: + // ____ DataInterpreter ____ + virtual InterpretedData interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const std::vector< rtl::Reference< ::chart::DataSeries > >& aSeriesToReUse ) override; + virtual InterpretedData reinterpretDataSeries( + const InterpretedData& aInterpretedData ) override; + virtual bool isDataCompatible( + const InterpretedData& aInterpretedData ) override; +}; + +} // namespace chart + +/* 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..553a13748 --- /dev/null +++ b/chart2/source/model/template/CandleStickChartType.cxx @@ -0,0 +1,348 @@ +/* -*- 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 )); +} + +rtl::Reference< ChartType > CandleStickChartType::cloneChartType() const +{ + return 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 ____ +void CandleStickChartType::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticCandleStickChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*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..e76107507 --- /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 . + */ +#pragma once + +#include <ChartType.hxx> + +namespace chart +{ + +// see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100797> "[10/11/12 Regression] using +// declaration causing virtual call with wrongly adjusted this pointer" before restoring 'final' +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; + + virtual rtl::Reference<ChartType> cloneChartType() const 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) 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 + +/* 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..eff91f9cc --- /dev/null +++ b/chart2/source/model/template/ChartType.cxx @@ -0,0 +1,335 @@ +/* -*- 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 <Axis.hxx> +#include <AxisHelper.hxx> +#include <CloneHelper.hxx> +#include <AxisIndexDefines.hxx> +#include <ModifyListenerHelper.hxx> +#include <DataSeries.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( new ModifyEventForwarder() ), + m_bNotifyChanges( true ) +{} + +ChartType::ChartType( const ChartType & rOther ) : + impl::ChartType_Base(rOther), + ::property::OPropertySet( rOther, m_aMutex ), + m_xModifyEventForwarder( new ModifyEventForwarder() ), + m_bNotifyChanges( true ) +{ + { + SolarMutexGuard g; // access to rOther.m_aDataSeries + CloneHelper::CloneRefVector( + 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 ) +{ + return createCoordinateSystem2(DimensionCount); +} + +rtl::Reference< BaseCoordinateSystem > + ChartType::createCoordinateSystem2( ::sal_Int32 DimensionCount ) +{ + rtl::Reference< CartesianCoordinateSystem > xResult = + new CartesianCoordinateSystem( DimensionCount ); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + rtl::Reference< Axis > xAxis = xResult->getAxisByDimension2( 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() +{ + return { "label", "values-y" }; +} + +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 rtl::Reference< DataSeries >& xDataSeries ) +{ + if( std::find( m_aDataSeries.begin(), m_aDataSeries.end(), xDataSeries ) + != m_aDataSeries.end()) + throw lang::IllegalArgumentException("dataseries not found", static_cast<cppu::OWeakObject*>(this), 1); + + m_aDataSeries.push_back( xDataSeries ); + ModifyListenerHelper::addListener( xDataSeries, m_xModifyEventForwarder ); +} + +// ____ XDataSeriesContainer ____ +void SAL_CALL ChartType::addDataSeries( const Reference< chart2::XDataSeries >& xDataSeries ) +{ + rtl::Reference<DataSeries> xTmp = dynamic_cast<DataSeries*>(xDataSeries.get()); + assert(xTmp); + addDataSeries(xTmp); +} + +void ChartType::addDataSeries( const rtl::Reference< DataSeries >& xDataSeries ) +{ + SolarMutexGuard g; + + impl_addDataSeriesWithoutNotification( xDataSeries ); + fireModifyEvent(); +} + +void SAL_CALL ChartType::removeDataSeries( const Reference< chart2::XDataSeries >& xDataSeries ) +{ + rtl::Reference<DataSeries> xTmp = dynamic_cast<DataSeries*>(xDataSeries.get()); + assert(xTmp); + removeDataSeries(xTmp); +} + +void ChartType::removeDataSeries( const rtl::Reference< DataSeries >& xDataSeries ) +{ + if( !xDataSeries.is()) + throw container::NoSuchElementException(); + + SolarMutexGuard g; + + auto 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< Reference< chart2::XDataSeries > >( m_aDataSeries ); +} + +void SAL_CALL ChartType::setDataSeries( const Sequence< Reference< chart2::XDataSeries > >& aDataSeries ) +{ + std::vector< rtl::Reference<DataSeries> > aTmp; + for (auto const & i : aDataSeries) + { + auto p = dynamic_cast<DataSeries*>(i.get()); + assert(p); + aTmp.push_back(p); + } + setDataSeries(aTmp); +} + +void ChartType::setDataSeries( const std::vector< rtl::Reference< DataSeries > >& aDataSeries ) +{ + SolarMutexGuard g; + + m_bNotifyChanges = false; + try + { + for( auto const & i : m_aDataSeries ) + 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 ____ +void ChartType::GetDefaultValue( sal_Int32 /* nHandle */, uno::Any& rAny ) const +{ + rAny.clear(); +} + +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 + { + m_xModifyEventForwarder->addModifyListener( aListener ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void SAL_CALL ChartType::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener ) +{ + try + { + m_xModifyEventForwarder->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/ChartTypeManager.cxx b/chart2/source/model/template/ChartTypeManager.cxx new file mode 100644 index 000000000..b1abde352 --- /dev/null +++ b/chart2/source/model/template/ChartTypeManager.cxx @@ -0,0 +1,588 @@ +/* -*- 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 <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 ) +{ + return static_cast<cppu::OWeakObject*>(createTemplate(aServiceSpecifier).get()); +} + +rtl::Reference< ::chart::ChartTypeTemplate > ChartTypeManager::createTemplate( + const OUString& aServiceSpecifier ) +{ + TemplateId nId = lcl_GetTemplateIdForService( aServiceSpecifier ); + + rtl::Reference< ::chart::ChartTypeTemplate > 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; + + case TEMPLATE_NOT_FOUND: + SAL_WARN("chart2", "Couldn't instantiate service: "<< aServiceSpecifier ); + assert(false); + break; + + default: break; +// case TEMPLATE_SURFACE: +// case TEMPLATE_ADDIN: +// break; + } + + return xTemplate; +} + +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..a785635f9 --- /dev/null +++ b/chart2/source/model/template/ChartTypeTemplate.cxx @@ -0,0 +1,861 @@ +/* -*- 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 <ChartType.hxx> +#include <DataSeries.hxx> +#include <DataSource.hxx> + +#include <Axis.hxx> +#include <AxisHelper.hxx> +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <AxisIndexDefines.hxx> +#include <BaseCoordinateSystem.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/XColorScheme.hpp> +#include <tools/diagnose_ex.h> +#include <comphelper/property.hxx> + +#include <algorithm> +#include <cstddef> + +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 rtl::Reference< ::chart::DataSeries > & xSeries, + sal_Int32 nIndex, + const rtl::Reference< ::chart::Diagram > & xDiagram ) +{ + // @deprecated: correct default color should be found by view without + // setting color as hard attribute + if( xSeries.is() && xDiagram.is()) + { + Reference< chart2::XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme()); + if( xColorScheme.is() ) + xSeries->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 rtl::Reference< ::chart::Diagram >& xDiagram, const rtl::Reference< ::chart::ChartType >& xChartType ) +{ + if( xDiagram.is() ) + { + uno::Sequence < sal_Int32 > aAvailableMissingValueTreatment( + ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) ); + + if( aAvailableMissingValueTreatment.hasElements() ) + xDiagram->setPropertyValue( "MissingValueTreatment", uno::Any( aAvailableMissingValueTreatment[0] ) ); + else + xDiagram->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() +{} + +// ____ ChartTypeTemplate ____ +rtl::Reference< Diagram > ChartTypeTemplate::createDiagramByDataSource2( + const uno::Reference< data::XDataSource >& xDataSource, + const uno::Sequence< beans::PropertyValue >& aArguments ) +{ + rtl::Reference< Diagram > xDia; + + try + { + // create diagram + xDia = new Diagram(GetComponentContext()); + + // modify diagram + rtl::Reference< DataInterpreter > xInterpreter( getDataInterpreter2()); + InterpretedData aData( + xInterpreter->interpretDataSource( + xDataSource, aArguments, {} )); + + sal_Int32 nCount = 0; + for( auto const & i : aData.Series ) + for( auto const & j : i ) + lcl_applyDefaultStyle( j, nCount++, xDia ); + + std::vector< rtl::Reference< ChartType > > 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 ChartTypeTemplate::changeDiagram( const rtl::Reference< Diagram >& xDiagram ) +{ + if( ! xDiagram.is()) + return; + + try + { + std::vector< std::vector< rtl::Reference< DataSeries > > > aSeriesSeq = + DiagramHelper::getDataSeriesGroups( xDiagram ); + std::vector< rtl::Reference< DataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq )); + const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.size(); + + // chart-type specific interpretation of existing data series + rtl::Reference< DataInterpreter > xInterpreter( getDataInterpreter2()); + InterpretedData aData; + aData.Series = aSeriesSeq; + aData.Categories = DiagramHelper::getCategoriesFromDiagram( xDiagram ); + + if( xInterpreter->isDataCompatible( aData ) ) + { + aData = xInterpreter->reinterpretDataSeries( aData ); + } + else + { + rtl::Reference< DataSource > xSource = DataInterpreter::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 = { 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 + std::vector< rtl::Reference< ChartType > > aOldChartTypesSeq = + DiagramHelper::getChartTypesFromDiagram(xDiagram); + + for( rtl::Reference< BaseCoordinateSystem > const & coords : xDiagram->getBaseCoordinateSystems() ) + { + coords->setChartTypes( Sequence< Reference< XChartType > >() ); + } + + FillDiagram( xDiagram, aSeriesSeq, aData.Categories, aOldChartTypesSeq ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void ChartTypeTemplate::changeDiagramData( + const rtl::Reference< Diagram >& 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 + std::vector< rtl::Reference< DataSeries > > aFlatSeriesSeq = + DiagramHelper::getDataSeriesFromDiagram( xDiagram ); + const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.size(); + rtl::Reference< DataInterpreter > xInterpreter( getDataInterpreter2()); + InterpretedData aData = + xInterpreter->interpretDataSource( xDataSource, aArguments, aFlatSeriesSeq ); + + // data series + sal_Int32 nIndex = 0; + for( std::size_t i=0; i<aData.Series.size(); ++i ) + for( std::size_t j=0; j<aData.Series[i].size(); ++j, ++nIndex ) + { + if( nIndex >= nFormerSeriesCount ) + { + lcl_applyDefaultStyle( aData.Series[i][j], nIndex, xDiagram ); + applyStyle2( aData.Series[i][j], i, j, aData.Series[i].size() ); + } + } + + // categories + DiagramHelper::setCategoriesToDiagram( aData.Categories, xDiagram, true, supportsCategories() ); + + std::vector< rtl::Reference< ChartType > > aChartTypes = + DiagramHelper::getChartTypesFromDiagram( xDiagram ); + sal_Int32 nMax = std::min( aChartTypes.size(), aData.Series.size()); + for( sal_Int32 i=0; i<nMax; ++i ) + { + aChartTypes[i]->setDataSeries( aData.Series[i] ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +bool ChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool /* bAdaptProperties */ ) +{ + bool bResult = false; + + if( ! xDiagram.is()) + return bResult; + + try + { + const std::vector< rtl::Reference< BaseCoordinateSystem > > & aCooSysSeq( + xDiagram->getBaseCoordinateSystems()); + + // need to have at least one coordinate system + bResult = !aCooSysSeq.empty(); + if( bResult ) + { + std::vector< rtl::Reference< ChartType > > aFormerlyUsedChartTypes; + rtl::Reference<ChartType> xOldCT = getChartTypeForNewSeries2(aFormerlyUsedChartTypes); + if (!xOldCT.is()) + return false; + + const OUString aChartTypeToMatch = xOldCT->getChartType(); + const sal_Int32 nDimensionToMatch = getDimension(); + for( std::size_t nCooSysIdx=0; bResult && (nCooSysIdx < aCooSysSeq.size()); ++nCooSysIdx ) + { + // match dimension + bResult = bResult && (aCooSysSeq[nCooSysIdx]->getDimension() == nDimensionToMatch); + + const std::vector< rtl::Reference< ChartType > > & aChartTypeSeq( aCooSysSeq[nCooSysIdx]->getChartTypes2()); + for( std::size_t nCTIdx=0; bResult && (nCTIdx < aChartTypeSeq.size()); ++nCTIdx ) + { + // 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; +} + +rtl::Reference< DataInterpreter > ChartTypeTemplate::getDataInterpreter2() +{ + if( ! m_xDataInterpreter.is()) + m_xDataInterpreter.set( new DataInterpreter ); + + return m_xDataInterpreter; +} + +void ChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 /* nSeriesIndex */, + ::sal_Int32 /* nSeriesCount */ ) +{ + // sset stacking mode + if( !xSeries.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 ); + xSeries->setPropertyValue( "StackingDirection", aPropValue ); + + //ensure valid label placement + { + uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements( + getChartTypeForIndex( nChartTypeIndex ), isSwapXAndY(), xSeries ) ); + lcl_ensureCorrectLabelPlacement( xSeries, aAvailablePlacements ); + + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xSeries->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 rtl::Reference< ::chart::Diagram >& xDiagram ) +{ + // apply chart-type specific styles, like "symbols on" for example + std::vector< std::vector< rtl::Reference< DataSeries > > > aNewSeriesSeq( + DiagramHelper::getDataSeriesGroups( xDiagram )); + for( std::size_t i=0; i<aNewSeriesSeq.size(); ++i ) + { + const sal_Int32 nNumSeries = aNewSeriesSeq[i].size(); + for( sal_Int32 j=0; j<nNumSeries; ++j ) + applyStyle2( aNewSeriesSeq[i][j], i, j, nNumSeries ); + } + + //ensure valid empty cell handling (for first chart type...) + lcl_ensureCorrectMissingValueTreatment( xDiagram, getChartTypeForIndex( 0 ) ); +} + +void ChartTypeTemplate::resetStyles2( const rtl::Reference< ::chart::Diagram >& xDiagram ) +{ + // reset number format if we had percent stacking on + bool bPercent = (getStackMode(0) == StackMode::YStackedPercent); + if( bPercent ) + { + const std::vector< rtl::Reference< Axis > > aAxisSeq( AxisHelper::getAllAxesOfDiagram( xDiagram ) ); + for( rtl::Reference< Axis > const & axis : aAxisSeq ) + { + if( AxisHelper::getDimensionIndexOfAxis( axis, xDiagram )== 1 ) + { + // set number format to source format + axis->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::Any(true)); + axis->setPropertyValue(CHART_UNONAME_NUMFMT, uno::Any()); + } + } + } + + //reset label placement if default + for( rtl::Reference< BaseCoordinateSystem > const & xCooSys : xDiagram->getBaseCoordinateSystems() ) + { + //iterate through all chart types in the current coordinate system + for( rtl::Reference< ChartType > const & xChartType : xCooSys->getChartTypes2() ) + { + //iterate through all series in this chart type + for( rtl::Reference< DataSeries > const & xSeries : xChartType->getDataSeries2() ) + { + uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements( + xChartType, isSwapXAndY(), xSeries ) ); + if(!aAvailablePlacements.hasElements()) + continue; + + sal_Int32 nDefaultPlacement = aAvailablePlacements[0]; + + lcl_resetLabelPlacementIfDefault( xSeries, nDefaultPlacement ); + + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xSeries->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 rtl::Reference< ::chart::Diagram > & xDiagram ) +{ + if( ! xDiagram.is()) + return; + std::vector< rtl::Reference< ChartType > > aFormerlyUsedChartTypes; + rtl::Reference< ChartType > xChartType( getChartTypeForNewSeries2(aFormerlyUsedChartTypes)); + if( ! xChartType.is()) + return; + rtl::Reference< BaseCoordinateSystem > xCooSys = xChartType->createCoordinateSystem2( getDimension()); + if( ! xCooSys.is()) + { + // chart type wants no coordinate systems + xDiagram->setCoordinateSystems( Sequence< Reference< XCoordinateSystem > >()); + return; + } + // #i69680# make grid of first y-axis visible (was in the CooSys CTOR before) + if( xCooSys->getDimension() >= 2 ) + { + rtl::Reference< Axis > xAxis = xCooSys->getAxisByDimension2( 1, 0 ); + if( xAxis.is()) + AxisHelper::makeGridVisible( xAxis->getGridProperties() ); + } + + std::vector< rtl::Reference< BaseCoordinateSystem > > aCoordinateSystems( + xDiagram->getBaseCoordinateSystems()); + + if( !aCoordinateSystems.empty() ) + { + bool bOk = true; + for( std::size_t i=0; bOk && i<aCoordinateSystems.size(); ++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.empty() ) + { + rtl::Reference< BaseCoordinateSystem > 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) + { + rtl::Reference< Axis > xAxis = xOldCooSys->getAxisByDimension2( nDimensionIndex, nAxisIndex ); + if( xAxis.is()) + { + xCooSys->setAxisByDimension( nDimensionIndex, xAxis, nAxisIndex ); + } + } + } + } + + // set new coordinate systems + aCoordinateSystems = { xCooSys }; + + xDiagram->setCoordinateSystems( aCoordinateSystems ); +} + +void ChartTypeTemplate::adaptScales( + const std::vector< rtl::Reference< BaseCoordinateSystem > > & 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( rtl::Reference< BaseCoordinateSystem > const & xCooSys : aCooSysSeq ) + { + try + { + // 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) + { + rtl::Reference< Axis > xAxis = xCooSys->getAxisByDimension2(nDimensionX,nI); + if( xAxis.is()) + { + ScaleData aData( xAxis->getScaleData() ); + aData.Categories = xCategories; + if(bSupportsCategories) + { + rtl::Reference< ChartType > xChartType = getChartTypeForNewSeries2({}); + 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) + { + rtl::Reference< Axis > xAxis = xCooSys->getAxisByDimension2( 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 rtl::Reference< ::chart::Diagram > & /* xDiagram */ ) +{ +} + +void ChartTypeTemplate::createAxes( + const std::vector< rtl::Reference< BaseCoordinateSystem > > & rCoordSys ) +{ + //create missing axes + if( rCoordSys.empty() ) + return; + + rtl::Reference< BaseCoordinateSystem > 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 std::vector< rtl::Reference< BaseCoordinateSystem > > & rCoordSys ) +{ + //adapt properties of existing axes and remove superfluous axes + + if( rCoordSys.empty() ) + return; + + for( rtl::Reference< BaseCoordinateSystem > 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++ ) + { + rtl::Reference< Axis > 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 ) + { + // set number format to source format + xAxis->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::Any(true)); + xAxis->setPropertyValue(CHART_UNONAME_NUMFMT, uno::Any()); + } + } + } + } + } +} + +sal_Int32 ChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension ) +{ + return (nDimension < getDimension()) ? 1 : 0; +} + +void ChartTypeTemplate::FillDiagram( + const rtl::Reference< ::chart::Diagram >& xDiagram, + const std::vector< std::vector< rtl::Reference< DataSeries > > >& aSeriesSeq, + const uno::Reference< chart2::data::XLabeledDataSequence >& xCategories, + const std::vector< rtl::Reference< ChartType > >& aOldChartTypesSeq ) +{ + adaptDiagram( xDiagram ); + + try + { + // create coordinate systems and scales + createCoordinateSystems( xDiagram ); + std::vector< rtl::Reference< BaseCoordinateSystem > > aCoordinateSystems( xDiagram->getBaseCoordinateSystems()); + 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 std::vector< std::vector< rtl::Reference< DataSeries > > > & aSeriesSeq, + const std::vector< rtl::Reference< BaseCoordinateSystem > > & rCoordSys, + const std::vector< rtl::Reference< ChartType > >& aOldChartTypesSeq ) +{ + if( rCoordSys.empty() ) + return; + + try + { + std::size_t nCooSysIdx=0; + rtl::Reference< ChartType > xCT; + if( aSeriesSeq.empty() ) + { + // we need a new chart type + xCT = getChartTypeForNewSeries2( aOldChartTypesSeq ); + rCoordSys[nCooSysIdx]->setChartTypes(std::vector{ xCT }); + } + else + { + for( std::size_t nSeriesIdx=0; nSeriesIdx<aSeriesSeq.size(); ++nSeriesIdx ) + { + if( nSeriesIdx == nCooSysIdx ) + { + // we need a new chart type + xCT = getChartTypeForNewSeries2( aOldChartTypesSeq ); + std::vector< rtl::Reference< ChartType > > aCTSeq( rCoordSys[nCooSysIdx]->getChartTypes2()); + if( !aCTSeq.empty()) + { + aCTSeq[0] = xCT; + rCoordSys[nCooSysIdx]->setChartTypes( aCTSeq ); + } + else + rCoordSys[nCooSysIdx]->addChartType( xCT ); + + xCT->setDataSeries( aSeriesSeq[nSeriesIdx] ); + } + else + { + // reuse existing chart type + OSL_ASSERT( xCT.is()); + std::vector< rtl::Reference< DataSeries > > aNewSeriesSeq = xCT->getDataSeries2(); + sal_Int32 nNewStartIndex = aNewSeriesSeq.size(); + aNewSeriesSeq.resize( nNewStartIndex + aSeriesSeq[nSeriesIdx].size() ); + std::copy( aSeriesSeq[nSeriesIdx].begin(), + aSeriesSeq[nSeriesIdx].end(), + aNewSeriesSeq.begin() + nNewStartIndex ); + xCT->setDataSeries( aNewSeriesSeq ); + } + + // spread the series over the available coordinate systems + if( rCoordSys.size() > (nCooSysIdx + 1) ) + ++nCooSysIdx; + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( + const std::vector< rtl::Reference< ChartType > > & rOldChartTypesSeq, + const rtl::Reference< ChartType > & xNewChartType ) +{ + if( !xNewChartType.is() ) + return; + + OUString aNewChartType( xNewChartType->getChartType() ); + + Reference< beans::XPropertySet > xSource; + for( rtl::Reference< ChartType > const & xOldType : rOldChartTypesSeq ) + { + if( xOldType.is() && xOldType->getChartType() == aNewChartType ) + { + xSource = xOldType; + if( xSource.is() ) + break; + } + } + if( xSource.is() ) + comphelper::copyProperties( xSource, xNewChartType ); +} + +css::uno::Reference< css::uno::XInterface > ChartTypeTemplate::getDataInterpreter() +{ + return static_cast<cppu::OWeakObject*>(getDataInterpreter2().get()); +} +css::uno::Reference< css::chart2::XDiagram > ChartTypeTemplate::createDiagramByDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xDataSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments ) +{ + return createDiagramByDataSource2(xDataSource, aArguments); +} +void ChartTypeTemplate::changeDiagram( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) +{ + changeDiagram(rtl::Reference<Diagram>(dynamic_cast<Diagram*>(xDiagram.get()))); +} +void ChartTypeTemplate::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 ) +{ + changeDiagramData(rtl::Reference<Diagram>(dynamic_cast<Diagram*>(xDiagram.get())), xDataSource, aArguments); +} +sal_Bool ChartTypeTemplate::matchesTemplate( + const css::uno::Reference<css::chart2::XDiagram >& xDiagram, + sal_Bool bAdaptProperties ) +{ + return matchesTemplate2(dynamic_cast<Diagram*>(xDiagram.get()), static_cast<bool>(bAdaptProperties)); +} +css::uno::Reference< ::css::chart2::XChartType > ChartTypeTemplate::getChartTypeForNewSeries( + const css::uno::Sequence< css::uno::Reference< css::chart2::XChartType > >& aFormerlyUsedChartTypes ) +{ + std::vector< rtl::Reference< ::chart::ChartType > > aTmp; + aTmp.reserve(aFormerlyUsedChartTypes.getLength()); + for (auto const & rxChartType : aFormerlyUsedChartTypes) + aTmp.push_back(dynamic_cast<ChartType*>(rxChartType.get())); + return getChartTypeForNewSeries2(aTmp); +} +void ChartTypeTemplate::applyStyle( + const css::uno::Reference< css::chart2::XDataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + applyStyle2(dynamic_cast<DataSeries*>(xSeries.get()), nChartTypeIndex, nSeriesIndex, nSeriesCount); +} +void ChartTypeTemplate::resetStyles( + const css::uno::Reference< css::chart2::XDiagram >& xDiagram ) +{ + resetStyles2(dynamic_cast<Diagram*>(xDiagram.get())); +} + +} // namespace chart + +/* 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..50fdca0e1 --- /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{ 0, 0 }; + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_BARCHARTTYPE_OVERLAP_SEQUENCE, aSeq ); + + aSeq = { 100, 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 )); +} + +rtl::Reference< ChartType > ColumnChartType::cloneChartType() const +{ + return new ColumnChartType( *this ); +} + +// ____ XChartType ____ +OUString SAL_CALL ColumnChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_COLUMN; +} + +uno::Sequence< OUString > ColumnChartType::getSupportedPropertyRoles() +{ + return { "FillColor", "BorderColor" }; +} + +// ____ OPropertySet ____ +void ColumnChartType::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = *StaticColumnChartTypeDefaults::get(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*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..2c6b3d762 --- /dev/null +++ b/chart2/source/model/template/ColumnChartType.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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) 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 + +/* 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..f0a18708a --- /dev/null +++ b/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx @@ -0,0 +1,356 @@ +/* -*- 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 "ColumnChartType.hxx" +#include "LineChartType.hxx" +#include <CommonConverters.hxx> +#include <BaseCoordinateSystem.hxx> +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <DataSeries.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/drawing/LineStyle.hpp> +#include <com/sun/star/uno/XComponentContext.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 +}; + +::chart::tPropertyValueMap& StaticColumnLineChartTypeTemplateDefaults() +{ + static ::chart::tPropertyValueMap aStaticDefaults = + []() + { + ::chart::tPropertyValueMap aOutMap; + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, PROP_COL_LINE_NUMBER_OF_LINES, 1 ); + return aOutMap; + }(); + return aStaticDefaults; +} + +::cppu::OPropertyArrayHelper& StaticColumnLineChartTypeTemplateInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper( + []() + { + std::vector< css::beans::Property > aProperties { + { "NumberOfLines", + PROP_COL_LINE_NUMBER_OF_LINES, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT } }; + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + }()); + return aPropHelper; +} + +uno::Reference< beans::XPropertySetInfo >& StaticColumnLineChartTypeTemplateInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(StaticColumnLineChartTypeTemplateInfoHelper() ) ); + return xPropertySetInfo; +} + +} // 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 ____ +void ColumnLineChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = StaticColumnLineChartTypeTemplateDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL ColumnLineChartTypeTemplate::getInfoHelper() +{ + return StaticColumnLineChartTypeTemplateInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ColumnLineChartTypeTemplate::getPropertySetInfo() +{ + return StaticColumnLineChartTypeTemplateInfo(); +} + +void ColumnLineChartTypeTemplate::createChartTypes( + const std::vector< std::vector< rtl::Reference< DataSeries > > > & aSeriesSeq, + const std::vector< rtl::Reference< BaseCoordinateSystem > > & rCoordSys, + const std::vector< rtl::Reference< ChartType > >& aOldChartTypesSeq ) +{ + if( rCoordSys.empty() ) + return; + + try + { + const std::vector< rtl::Reference< DataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq )); + sal_Int32 nNumberOfSeries = aFlatSeriesSeq.size(); + 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 + + rtl::Reference< ChartType > xCT = new ColumnChartType(); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aOldChartTypesSeq, xCT ); + + rCoordSys[ 0 ]->setChartTypes( std::vector{xCT} ); + + if( nNumberOfColumns > 0 ) + { + std::vector< rtl::Reference< DataSeries > > aColumnSeq( nNumberOfColumns ); + std::copy( aFlatSeriesSeq.begin(), + aFlatSeriesSeq.begin() + nNumberOfColumns, + aColumnSeq.begin()); + xCT->setDataSeries( aColumnSeq ); + } + + // Lines + + xCT = new LineChartType(); + rCoordSys[ 0 ]->addChartType( xCT ); + + if( nNumberOfLines > 0 ) + { + std::vector< rtl::Reference< DataSeries > > aLineSeq( nNumberOfLines ); + std::copy( aFlatSeriesSeq.begin() + nNumberOfColumns, + aFlatSeriesSeq.end(), + aLineSeq.begin()); + xCT->setDataSeries( aLineSeq ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void ColumnLineChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + if( nChartTypeIndex==0 ) // columns + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "BorderStyle", uno::Any( drawing::LineStyle_NONE ) ); + } + else if( nChartTypeIndex==1 ) // lines + { + DataSeriesHelper::switchLinesOnOrOff( xSeries, true ); + DataSeriesHelper::switchSymbolsOnOrOff( xSeries, false, nSeriesIndex ); + DataSeriesHelper::makeLinesThickOrThin( xSeries, true ); + } +} + +StackMode ColumnLineChartTypeTemplate::getStackMode( sal_Int32 nChartTypeIndex ) const +{ + if( nChartTypeIndex == 0 ) + return m_eStackMode; + return StackMode::NONE; +} + +// ____ XChartTypeTemplate ____ +bool ColumnLineChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) +{ + bool bResult = false; + + if( ! xDiagram.is()) + return bResult; + + try + { + rtl::Reference< ChartType > xColumnChartType; + rtl::Reference< BaseCoordinateSystem > xColumnChartCooSys; + rtl::Reference< ChartType > xLineChartType; + sal_Int32 nNumberOfChartTypes = 0; + + for( rtl::Reference< BaseCoordinateSystem > const & coords : xDiagram->getBaseCoordinateSystems() ) + { + const std::vector< rtl::Reference< ChartType > > aChartTypeSeq( coords->getChartTypes2()); + for( rtl::Reference< ChartType > const & chartType : aChartTypeSeq ) + { + ++nNumberOfChartTypes; + if( nNumberOfChartTypes > 2 ) + break; + OUString aCTService = chartType->getChartType(); + if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ) + { + xColumnChartType = chartType; + xColumnChartCooSys = coords; + } + else if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_LINE ) + xLineChartType = 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 ) + { + if( xLineChartType.is() ) + { + sal_Int32 nNumberOfLines = xLineChartType->getDataSeries().getLength(); + setFastPropertyValue_NoBroadcast( PROP_COL_LINE_NUMBER_OF_LINES, uno::Any( nNumberOfLines )); + } + } + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return bResult; +} + +rtl::Reference< ChartType > ColumnLineChartTypeTemplate::getChartTypeForIndex( sal_Int32 nChartTypeIndex ) +{ + if( nChartTypeIndex == 0 ) + return new ColumnChartType(); + else + return new LineChartType(); +} + +rtl::Reference< ChartType > ColumnLineChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new LineChartType(); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +rtl::Reference< DataInterpreter > ColumnLineChartTypeTemplate::getDataInterpreter2() +{ + if( ! m_xDataInterpreter.is()) + { + sal_Int32 nNumberOfLines = 1; + getFastPropertyValue( PROP_COL_LINE_NUMBER_OF_LINES ) >>= nNumberOfLines; + m_xDataInterpreter = 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..f76f329a1 --- /dev/null +++ b/chart2/source/model/template/ColumnLineChartTypeTemplate.hxx @@ -0,0 +1,95 @@ +/* -*- 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 . + */ +#pragma once + +#include <ChartTypeTemplate.hxx> +#include <StackMode.hxx> + +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class ColumnLineChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ ChartTypeTemplate ____ + virtual bool matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual rtl::Reference< ::chart::DataInterpreter > getDataInterpreter2() override; + + // ____ ChartTypeTemplate ____ + virtual void createChartTypes( + const std::vector< + std::vector< + rtl::Reference< + ::chart::DataSeries > > > & aSeriesSeq, + const std::vector< + rtl::Reference< + ::chart::BaseCoordinateSystem > > & rCoordSys, + const std::vector< rtl::Reference< ChartType > > & aOldChartTypesSeq + ) override; + + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + + virtual StackMode getStackMode( sal_Int32 nChartTypeIndex ) const override; + +private: + StackMode m_eStackMode; +}; + +} // namespace chart + +/* 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..15ce4adce --- /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 <DataSeries.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 ) : + m_nNumberOfLines( nNumberOfLines ) +{} + +ColumnLineDataInterpreter::~ColumnLineDataInterpreter() +{} + +// ____ DataInterpreter ____ +InterpretedData ColumnLineDataInterpreter::interpretDataSource( + const Reference< data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const std::vector< rtl::Reference< DataSeries > >& aSeriesToReUse ) +{ + InterpretedData aResult( DataInterpreter::interpretDataSource( xSource, aArguments, aSeriesToReUse )); + + // the base class should return one group + OSL_ASSERT( aResult.Series.size() == 1 ); + if( aResult.Series.size() == 1 ) + { + sal_Int32 nNumberOfSeries = aResult.Series[0].size(); + + // 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.resize(2); + + std::vector< rtl::Reference< DataSeries > > & rColumnDataSeries = aResult.Series[0]; + std::vector< rtl::Reference< DataSeries > > & rLineDataSeries = aResult.Series[1]; + rLineDataSeries.resize( nNumOfLines ); + std::copy( std::cbegin(rColumnDataSeries) + nNumberOfSeries - nNumOfLines, + std::cbegin(rColumnDataSeries) + nNumberOfSeries, + rLineDataSeries.begin() ); + rColumnDataSeries.resize( 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..c2ec75826 --- /dev/null +++ b/chart2/source/model/template/ColumnLineDataInterpreter.hxx @@ -0,0 +1,44 @@ +/* -*- 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 . + */ +#pragma once + +#include <DataInterpreter.hxx> + +namespace chart +{ +class ColumnLineDataInterpreter : public DataInterpreter +{ +public: + explicit ColumnLineDataInterpreter(sal_Int32 nNumberOfLines); + virtual ~ColumnLineDataInterpreter() override; + +protected: + // ____ DataInterpreter ____ + virtual InterpretedData interpretDataSource( + const css::uno::Reference<css::chart2::data::XDataSource>& xSource, + const css::uno::Sequence<css::beans::PropertyValue>& aArguments, + const std::vector<rtl::Reference<::chart::DataSeries>>& aSeriesToReUse) override; + +private: + sal_Int32 m_nNumberOfLines; +}; + +} // namespace chart + +/* 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..5b8899dcc --- /dev/null +++ b/chart2/source/model/template/DataInterpreter.cxx @@ -0,0 +1,445 @@ +/* -*- 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 <DataSource.hxx> +#include <DataSeriesHelper.hxx> +#include <CommonConverters.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <tools/diagnose_ex.h> + +#include <algorithm> +#include <cstddef> + +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 DataInterpreter::interpretDataSource( + const Reference< data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const std::vector< rtl::Reference< DataSeries > >& aSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + +#ifdef DEBUG_CHART2_TEMPLATE + lcl_ShowDataSource( xSource ); +#endif + + std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aData = getDataSequences(xSource); + + uno::Reference< chart2::data::XLabeledDataSequence > xCategories; + vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSequencesVec; + + // check if we should use categories + + bool bHasCategories( HasCategories( aArguments, aData )); + + // parse data + bool bCategoriesUsed = false; + for( uno::Reference< chart2::data::XLabeledDataSequence > const & labeledData : aData ) + { + try + { + if( bHasCategories && ! bCategoriesUsed ) + { + xCategories = 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 + std::size_t nSeriesIndex = 0; + vector< rtl::Reference< DataSeries > > aSeriesVec; + aSeriesVec.reserve( aSequencesVec.size()); + + for (auto const& elem : aSequencesVec) + { + std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aNewData { elem }; + rtl::Reference< DataSeries > xSeries; + if( nSeriesIndex < aSeriesToReUse.size()) + xSeries = aSeriesToReUse[nSeriesIndex]; + else + xSeries = new DataSeries; + assert( xSeries.is() ); + xSeries->setData( aNewData ); + + aSeriesVec.push_back( xSeries ); + ++nSeriesIndex; + } + + return { { aSeriesVec }, xCategories }; +} + +InterpretedData DataInterpreter::reinterpretDataSeries( + const InterpretedData& aInterpretedData ) +{ + InterpretedData aResult( aInterpretedData ); + + sal_Int32 i=0; + std::vector< rtl::Reference< DataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + const sal_Int32 nCount = aSeries.size(); + for( ; i<nCount; ++i ) + { + try + { + std::vector< uno::Reference< data::XLabeledDataSequence > > aNewSequences; + + // values-y + uno::Reference< data::XLabeledDataSequence > xValuesY = + DataSeriesHelper::getDataSequenceByRole( aSeries[i], "values-y" ); + // re-use values-... as values-y + if( ! xValuesY.is()) + { + xValuesY = + DataSeriesHelper::getDataSequenceByRole( aSeries[i], "values", true ); + if( xValuesY.is()) + SetRole( xValuesY->getValues(), "values-y"); + } + if( xValuesY.is()) + { + aNewSequences = { xValuesY }; + } + + const std::vector< uno::Reference< data::XLabeledDataSequence > > & aSeqs = aSeries[i]->getDataSequences2(); + if( aSeqs.size() != aNewSequences.size() ) + { +#ifdef DEBUG_CHART2_TEMPLATE + sal_Int32 j=0; + for( ; j<aSeqs.(); ++j ) + { + assert( aSeqs[j] == xValuesY && "All sequences should be used" ); + } +#endif + aSeries[i]->setData( aNewSequences ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return aResult; +} + +// criterion: all series must have exactly one data::XLabeledDataSequence +bool DataInterpreter::isDataCompatible( + const InterpretedData& aInterpretedData ) +{ + const std::vector< rtl::Reference< DataSeries > > aSeries( FlattenSequence( aInterpretedData.Series )); + for( rtl::Reference< DataSeries > const & i : aSeries ) + { + try + { + if( i->getDataSequences2().size() != 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 + +rtl::Reference< DataSource > DataInterpreter::mergeInterpretedData( + const InterpretedData& aInterpretedData ) +{ + vector< Reference< data::XLabeledDataSequence > > aResultVec; + aResultVec.reserve( aInterpretedData.Series.size() + + 1 // categories + ); + + if( aInterpretedData.Categories.is()) + aResultVec.push_back( aInterpretedData.Categories ); + + const std::vector< rtl::Reference< DataSeries > > aSeries = FlattenSequence( aInterpretedData.Series ); + for( rtl::Reference< DataSeries > const & dataSeries : aSeries ) + { + try + { + // add all sequences of data series + for( uno::Reference< data::XLabeledDataSequence > const & xAdd : dataSeries->getDataSequences2() ) + { + // 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 new DataSource(aResultVec); +} + +uno::Any DataInterpreter::getChartTypeSpecificData( + const OUString & ) +{ + return uno::Any(); +} + +// 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, + std::u16string_view 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 std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > & rData ) +{ + bool bHasCategories = false; + + if( rArguments.hasElements() ) + GetProperty( rArguments, u"HasCategories" ) >>= bHasCategories; + + for( std::size_t nLSeqIdx=0; ! bHasCategories && nLSeqIdx<rData.size(); ++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, u"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" }; +} + +std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > DataInterpreter::getDataSequences( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource) +{ + std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aData; + for (const Reference< data::XLabeledDataSequence > & rLDS : xSource->getDataSequences() ) + { + aData.push_back(rLDS); + } + return aData; +} + +} // 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/FilledNetChartType.cxx b/chart2/source/model/template/FilledNetChartType.cxx new file mode 100644 index 000000000..6ec39d983 --- /dev/null +++ b/chart2/source/model/template/FilledNetChartType.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 "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 )); +} + +rtl::Reference< ChartType > FilledNetChartType::cloneChartType() const +{ + return 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..b2d239aec --- /dev/null +++ b/chart2/source/model/template/FilledNetChartType.hxx @@ -0,0 +1,49 @@ +/* -*- 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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const 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 + +/* 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..e9d7cf808 --- /dev/null +++ b/chart2/source/model/template/LineChartType.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 "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 +}; + +::chart::tPropertyValueMap& StaticLineChartTypeDefaults() +{ + static ::chart::tPropertyValueMap aStaticDefaults = + []() + { + ::chart::tPropertyValueMap aOutMap; + ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_LINECHARTTYPE_CURVE_STYLE, ::chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, 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 >( aOutMap, PROP_LINECHARTTYPE_SPLINE_ORDER, 3 ); + return aOutMap; + }(); + return aStaticDefaults; +} + +::cppu::OPropertyArrayHelper& StaticLineChartTypeInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper( + []() + { + std::vector< css::beans::Property > aProperties { + { CHART_UNONAME_CURVE_STYLE, + PROP_LINECHARTTYPE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_CURVE_RESOLUTION, + PROP_LINECHARTTYPE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_SPLINE_ORDER, + PROP_LINECHARTTYPE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT } }; + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + }()); + return aPropHelper; +} + +uno::Reference< beans::XPropertySetInfo >& StaticLineChartTypeInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(StaticLineChartTypeInfoHelper() ) ); + return xPropertySetInfo; +} + +} // 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 )); +} + +rtl::Reference< ChartType > LineChartType::cloneChartType() const +{ + return new LineChartType( *this ); +} + +// ____ XChartType ____ +OUString SAL_CALL LineChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_LINE; +} + +// ____ OPropertySet ____ +void LineChartType::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = StaticLineChartTypeDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL LineChartType::getInfoHelper() +{ + return StaticLineChartTypeInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL LineChartType::getPropertySetInfo() +{ + return StaticLineChartTypeInfo(); +} + +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..4c44cca9c --- /dev/null +++ b/chart2/source/model/template/LineChartType.hxx @@ -0,0 +1,61 @@ +/* -*- 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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const override; + +private: + explicit LineChartType( const LineChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + + // ____ OPropertySet ____ + virtual void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) 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 + +/* 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..65ce8def4 --- /dev/null +++ b/chart2/source/model/template/LineChartTypeTemplate.cxx @@ -0,0 +1,329 @@ +/* -*- 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 "LineChartType.hxx" +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <PropertyHelper.hxx> +#include <ChartType.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 <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 + +}; + +::chart::tPropertyValueMap& StaticLineChartTypeTemplateDefaults() +{ + static ::chart::tPropertyValueMap aStaticDefaults = + []() + { + ::chart::tPropertyValueMap aOutMap; + ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE, chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, 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 >( aOutMap, PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER, 3 ); + return aOutMap; + }(); + return aStaticDefaults; +} + +::cppu::OPropertyArrayHelper& StaticLineChartTypeTemplateInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper( + []() + { + std::vector< css::beans::Property > aProperties { + { CHART_UNONAME_CURVE_STYLE, + PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_CURVE_RESOLUTION, + PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_SPLINE_ORDER, + PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT } }; + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + }()); + return aPropHelper; +} + +uno::Reference< beans::XPropertySetInfo >& StaticLineChartTypeTemplateInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(StaticLineChartTypeTemplateInfoHelper() ) ); + return xPropertySetInfo; +} + +} // 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 ____ +void LineChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = StaticLineChartTypeTemplateDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL LineChartTypeTemplate::getInfoHelper() +{ + return StaticLineChartTypeTemplateInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL LineChartTypeTemplate::getPropertySetInfo() +{ + return StaticLineChartTypeTemplateInfo(); +} + +sal_Int32 LineChartTypeTemplate::getDimension() const +{ + return m_nDim; +} + +StackMode LineChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const +{ + return m_eStackMode; +} + +// ____ ChartTypeTemplate ____ +bool LineChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate2( 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< rtl::Reference< DataSeries > > aSeriesVec = + DiagramHelper::getDataSeriesFromDiagram( xDiagram ); + + for (auto const& series : aSeriesVec) + { + try + { + chart2::Symbol aSymbProp; + drawing::LineStyle eLineStyle; + + bool bCurrentHasSymbol = (series->getPropertyValue( "Symbol") >>= aSymbProp) && + (aSymbProp.Style != chart2::SymbolStyle_NONE); + + if( bCurrentHasSymbol ) + bSymbolFound = true; + + if( bCurrentHasSymbol && (!m_bHasSymbols) ) + { + bResult = false; + break; + } + + bool bCurrentHasLine = (series->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 + { + rtl::Reference< ChartType > xChartType = + DiagramHelper::getChartTypeByIndex( xDiagram, 0 ); + setFastPropertyValue_NoBroadcast( PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE, xChartType->getPropertyValue(CHART_UNONAME_CURVE_STYLE) ); + setFastPropertyValue_NoBroadcast( PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION, xChartType->getPropertyValue(CHART_UNONAME_CURVE_RESOLUTION) ); + setFastPropertyValue_NoBroadcast( PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER, xChartType->getPropertyValue(CHART_UNONAME_SPLINE_ORDER) ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return bResult; +} + +rtl::Reference< ChartType > LineChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new LineChartType(); + + xResult->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE )); + xResult->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xResult->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +rtl::Reference< ChartType > LineChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new LineChartType(); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + + xResult->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_STYLE )); + xResult->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xResult->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_LINECHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +void LineChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + DataSeriesHelper::switchSymbolsOnOrOff( xSeries, m_bHasSymbols, nSeriesIndex ); + DataSeriesHelper::switchLinesOnOrOff( xSeries, m_bHasLines ); + DataSeriesHelper::makeLinesThickOrThin( xSeries, 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..88ad1a7da --- /dev/null +++ b/chart2/source/model/template/LineChartTypeTemplate.hxx @@ -0,0 +1,85 @@ +/* -*- 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 . + */ +#pragma once + +#include <ChartTypeTemplate.hxx> +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <StackMode.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class LineChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ ChartTypeTemplate ____ + virtual bool matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual rtl::Reference< ::chart::ChartType > + 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 + +/* 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..cb4512c74 --- /dev/null +++ b/chart2/source/model/template/NetChartType.cxx @@ -0,0 +1,175 @@ +/* -*- 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 <Axis.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() +{} + +rtl::Reference< ::chart::BaseCoordinateSystem > + NetChartType_Base::createCoordinateSystem2( sal_Int32 DimensionCount ) +{ + if( DimensionCount != 2 ) + throw lang::IllegalArgumentException( + "NetChart must be two-dimensional", + static_cast< ::cppu::OWeakObject* >( this ), 0 ); + + rtl::Reference< PolarCoordinateSystem > xResult = + new PolarCoordinateSystem( DimensionCount ); + + rtl::Reference< Axis > xAxis = xResult->getAxisByDimension2( 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->getAxisByDimension2( 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 ____ +void NetChartType_Base::GetDefaultValue( sal_Int32 /*nHandle*/, uno::Any& rAny ) const +{ + rAny.clear(); +} + +namespace +{ + +::cppu::OPropertyArrayHelper& StaticNetChartTypeInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper(Sequence< beans::Property >{}); + return aPropHelper; +} + +uno::Reference< beans::XPropertySetInfo >& StaticNetChartTypeInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(StaticNetChartTypeInfoHelper() ) ); + return xPropertySetInfo; +} + +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL NetChartType_Base::getInfoHelper() +{ + return StaticNetChartTypeInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL NetChartType_Base::getPropertySetInfo() +{ + return StaticNetChartTypeInfo(); +} + +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 )); +} + +rtl::Reference< ChartType > NetChartType::cloneChartType() const +{ + return 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..ae414a27c --- /dev/null +++ b/chart2/source/model/template/NetChartType.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 . + */ +#pragma once + +#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 ); + + // ____ OPropertySet ____ + virtual void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + virtual rtl::Reference< ::chart::BaseCoordinateSystem > + createCoordinateSystem2( sal_Int32 DimensionCount ) 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; + + virtual rtl::Reference<ChartType> cloneChartType() const 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 + +/* 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..158bffe0b --- /dev/null +++ b/chart2/source/model/template/NetChartTypeTemplate.cxx @@ -0,0 +1,175 @@ +/* -*- 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 "FilledNetChartType.hxx" +#include "NetChartType.hxx" +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <ChartType.hxx> +#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 NetChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + DataSeriesHelper::switchSymbolsOnOrOff( xSeries, m_bHasSymbols, nSeriesIndex ); + DataSeriesHelper::switchLinesOnOrOff( xSeries, m_bHasLines ); + DataSeriesHelper::makeLinesThickOrThin( xSeries, true ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ ChartTypeTemplate ____ +bool NetChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate2( xDiagram, bAdaptProperties ); + + 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< rtl::Reference< DataSeries > > aSeriesVec = + DiagramHelper::getDataSeriesFromDiagram( xDiagram ); + + for (auto const& series : aSeriesVec) + { + try + { + chart2::Symbol aSymbProp; + drawing::LineStyle eLineStyle; + + bool bCurrentHasSymbol = (series->getPropertyValue( "Symbol") >>= aSymbProp) && + (aSymbProp.Style != chart2::SymbolStyle_NONE); + + if( bCurrentHasSymbol ) + bSymbolFound = true; + + if( bCurrentHasSymbol && (!m_bHasSymbols) ) + { + bResult = false; + break; + } + + bool bCurrentHasLine = (series->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; +} + +rtl::Reference< ChartType > NetChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + if( m_bHasFilledArea ) + return new FilledNetChartType(); + else + return new NetChartType(); +} + +rtl::Reference< ChartType > NetChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > 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..b1f5ac9db --- /dev/null +++ b/chart2/source/model/template/NetChartTypeTemplate.hxx @@ -0,0 +1,68 @@ +/* -*- 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 . + */ +#pragma once + +#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: + // ____ ChartTypeTemplate ____ + virtual bool matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + + // ____ ChartTypeTemplate ____ + virtual rtl::Reference< ::chart::ChartType > + 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 + +/* 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..fdbfc7ced --- /dev/null +++ b/chart2/source/model/template/PieChartType.cxx @@ -0,0 +1,215 @@ +/* -*- 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 <Axis.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 +}; + + +::chart::tPropertyValueMap& StaticPieChartTypeDefaults() +{ + static ::chart::tPropertyValueMap aStaticDefaults = + []() + { + ::chart::tPropertyValueMap aOutMap; + ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIECHARTTYPE_USE_RINGS, false ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, PROP_PIECHARTTYPE_3DRELATIVEHEIGHT, 100 ); + return aOutMap; + }(); + return aStaticDefaults; +} + +::cppu::OPropertyArrayHelper& StaticPieChartTypeInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper( + []() + { + std::vector< css::beans::Property > aProperties { + { "UseRings", + PROP_PIECHARTTYPE_USE_RINGS, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { "3DRelativeHeight", + PROP_PIECHARTTYPE_3DRELATIVEHEIGHT, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::MAYBEVOID } + }; + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + }()); + return aPropHelper; +} + +uno::Reference< beans::XPropertySetInfo >& StaticPieChartTypeInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo( StaticPieChartTypeInfoHelper() ) ); + return xPropertySetInfo; +} + +} // 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 )); +} + +rtl::Reference< ChartType > PieChartType::cloneChartType() const +{ + return new PieChartType( *this ); +} + +// ____ XChartType ____ +OUString SAL_CALL PieChartType::getChartType() +{ + return CHART2_SERVICE_NAME_CHARTTYPE_PIE; +} + +rtl::Reference< ::chart::BaseCoordinateSystem > + PieChartType::createCoordinateSystem2( sal_Int32 DimensionCount ) +{ + rtl::Reference< PolarCoordinateSystem > xResult = + new PolarCoordinateSystem( DimensionCount ); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + rtl::Reference< Axis > xAxis = xResult->getAxisByDimension2( 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() +{ + return { "FillColor", "BorderColor" }; +} + +// ____ OPropertySet ____ +void PieChartType::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = StaticPieChartTypeDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL PieChartType::getInfoHelper() +{ + return StaticPieChartTypeInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL PieChartType::getPropertySetInfo() +{ + return StaticPieChartTypeInfo(); +} + +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..5a1e46f43 --- /dev/null +++ b/chart2/source/model/template/PieChartType.hxx @@ -0,0 +1,68 @@ +/* -*- 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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const override; + +private: + explicit PieChartType( const PieChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedPropertyRoles() override; + + // ____ OPropertySet ____ + virtual void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) 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; + + virtual rtl::Reference< ::chart::BaseCoordinateSystem > + createCoordinateSystem2( sal_Int32 DimensionCount ) override; +}; + +} // namespace chart + +/* 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..c8d82b761 --- /dev/null +++ b/chart2/source/model/template/PieChartTypeTemplate.cxx @@ -0,0 +1,567 @@ +/* -*- 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 "PieChartType.hxx" +#include <BaseCoordinateSystem.hxx> +#include <CommonConverters.hxx> +#include <ChartType.hxx> +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <Axis.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/uno/XComponentContext.hpp> +#include <officecfg/Office/Compatibility.hxx> +#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 +}; + +::chart::tPropertyValueMap& StaticPieChartTypeTemplateDefaults() +{ + static ::chart::tPropertyValueMap aStaticDefaults = + []{ + ::chart::tPropertyValueMap aOutMap; + ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIE_TEMPLATE_OFFSET_MODE, chart2::PieChartOffsetMode_NONE ); + ::chart::PropertyHelper::setPropertyValueDefault< double >( aOutMap, PROP_PIE_TEMPLATE_DEFAULT_OFFSET, 0.5 ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, PROP_PIE_TEMPLATE_DIMENSION, 2 ); + ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIE_TEMPLATE_USE_RINGS, false ); + return aOutMap; + }(); + return aStaticDefaults; +} + +::cppu::OPropertyArrayHelper& StaticPieChartTypeTemplateInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper( + []() + { + std::vector< css::beans::Property > aProperties { + { "OffsetMode", + PROP_PIE_TEMPLATE_OFFSET_MODE, + cppu::UnoType<chart2::PieChartOffsetMode>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { "DefaultOffset", + PROP_PIE_TEMPLATE_DEFAULT_OFFSET, + cppu::UnoType<double>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { "Dimension", + PROP_PIE_TEMPLATE_DIMENSION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { "UseRings", + PROP_PIE_TEMPLATE_USE_RINGS, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT } }; + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + }() ); + return aPropHelper; +} + +uno::Reference< beans::XPropertySetInfo >& StaticPieChartTypeTemplateInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(StaticPieChartTypeTemplateInfoHelper() ) ); + return xPropertySetInfo; +} + +} // 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 ____ +void PieChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = StaticPieChartTypeTemplateDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL PieChartTypeTemplate::getInfoHelper() +{ + return StaticPieChartTypeTemplateInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL PieChartTypeTemplate::getPropertySetInfo() +{ + return StaticPieChartTypeTemplateInfo(); +} + +// ____ 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 std::vector< rtl::Reference< BaseCoordinateSystem > > & /*rCoordSys*/ ) +{ + // hide existing axes + //hhhh todo +} + +void PieChartTypeTemplate::adaptScales( + const std::vector< rtl::Reference< BaseCoordinateSystem > > & 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( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysSeq ) + { + try + { + rtl::Reference< Axis > xAxis = AxisHelper::getAxis( 1 /*nDimensionIndex*/,0 /*nAxisIndex*/ + , coords ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData() ); + AxisHelper::removeExplicitScaling( aScaleData ); + // tdf#108059 Create new pie/donut charts with clockwise orientation + if (!officecfg::Office::Compatibility::View::ClockwisePieChartDirection::get()) + { + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + } + else + { + aScaleData.Orientation = chart2::AxisOrientation_REVERSE; + } + xAxis->setScaleData( aScaleData ); + } + + xAxis = AxisHelper::getAxis( 0 /*nDimensionIndex*/,0 /*nAxisIndex*/ + , coords ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData() ); + + //tdf#123218 Don't reverse the orientation in OOXML-heavy environments + if( officecfg::Office::Compatibility::View::ReverseXAxisOrientationDoughnutChart::get() ) + aScaleData.Orientation = chart2::AxisOrientation_REVERSE; + else + aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL; + xAxis->setScaleData( aScaleData ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } +} + +void PieChartTypeTemplate::createChartTypes( + const std::vector< std::vector< rtl::Reference< DataSeries > > > & aSeriesSeq, + const std::vector< rtl::Reference< BaseCoordinateSystem > > & rCoordSys, + const std::vector< rtl::Reference< ChartType > >& /* aOldChartTypesSeq */ ) +{ + if( rCoordSys.empty() ) + return; + + try + { + rtl::Reference< ChartType > xCT = new PieChartType(); + xCT->setPropertyValue( + "UseRings", getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); + rCoordSys[0]->setChartTypes( std::vector{xCT} ); + + if( !aSeriesSeq.empty() ) + { + std::vector< rtl::Reference< DataSeries > > aFlatSeriesSeq = FlattenSequence( aSeriesSeq ); + xCT->setDataSeries( aFlatSeriesSeq ); + + DataSeriesHelper::setStackModeAtSeries( + aFlatSeriesSeq, rCoordSys[0], getStackMode( 0 )); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ XChartTypeTemplate ____ +bool PieChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate2( 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; + sal_Int32 nOuterSeriesIndex = 0; + + std::vector< rtl::Reference< DataSeries > > aSeriesVec = + DiagramHelper::getDataSeriesFromDiagram( xDiagram ); + + //tdf#108067 The outer series is the last series in OOXML-heavy environments + if( !officecfg::Office::Compatibility::View::ReverseXAxisOrientationDoughnutChart::get() ) + nOuterSeriesIndex = aSeriesVec.size() - 1; + + //check offset of outer series + if( !aSeriesVec.empty() ) + { + //@todo in future this will depend on Orientation of the radius axis scale + rtl::Reference< DataSeries > xSeries( aSeriesVec[nOuterSeriesIndex] ); + xSeries->getPropertyValue( "Offset") >>= fOffset; + + //get AttributedDataPoints + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xSeries->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( xSeries->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 ) + { + rtl::Reference< ChartType > xCTProp = + DiagramHelper::getChartTypeByIndex( xDiagram, 0 ); + bool bUseRings = false; + if( xCTProp->getPropertyValue( "UseRings") >>= bUseRings ) + { + bResult = ( bTemplateUsesRings == bUseRings ); + } + } + + return bResult; +} + +rtl::Reference< ChartType > PieChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new PieChartType(); + xResult->setPropertyValue( + "UseRings", getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +rtl::Reference< ChartType > PieChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new PieChartType(); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + xResult->setPropertyValue( + "UseRings", getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +void PieChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + bool bTemplateUsesRings = false; + sal_Int32 nOuterSeriesIndex = 0; + getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ) >>= bTemplateUsesRings; + + //tdf#108067 The outer series is the last series in OOXML-heavy environments + if( !officecfg::Office::Compatibility::View::ReverseXAxisOrientationDoughnutChart::get() ) + nOuterSeriesIndex = nSeriesCount - 1; + + if( nSeriesIndex == nOuterSeriesIndex ) //@todo in future this will depend on Orientation of the radius axis scale + { + static const OUStringLiteral aOffsetPropName( u"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; + xSeries->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( (xSeries->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 + xSeries->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 + xSeries->setPropertyValue( "VaryColorsByPoint", uno::Any( true )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void PieChartTypeTemplate::resetStyles2( const rtl::Reference< ::chart::Diagram >& xDiagram ) +{ + // reset axes and grids + if( xDiagram.is()) + { + const std::vector< rtl::Reference< BaseCoordinateSystem > > aCooSysSeq( xDiagram->getBaseCoordinateSystems()); + ChartTypeTemplate::createAxes( aCooSysSeq ); + + //reset scale orientation + for( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysSeq ) + { + try + { + rtl::Reference< Axis > 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::resetStyles2( xDiagram ); + + // vary colors by point, + // line style + std::vector< rtl::Reference< DataSeries > > aSeriesVec = + DiagramHelper::getDataSeriesFromDiagram( xDiagram ); + uno::Any aLineStyleAny( drawing::LineStyle_NONE ); + for (auto const& series : aSeriesVec) + { + series->setPropertyToDefault( "VaryColorsByPoint"); + if( series->getPropertyValue( "BorderStyle") == aLineStyleAny ) + { + series->setPropertyToDefault( "BorderStyle"); + } + } + + //reset scene properties + ThreeDHelper::setDefaultRotation( xDiagram, false ); +} + +// ____ XChartTypeTemplate ____ +void PieChartTypeTemplate::adaptDiagram( const rtl::Reference< ::chart::Diagram >& xDiagram ) +{ + if( !xDiagram.is() ) + return; + + //different default for scene geometry: + ThreeDHelper::setDefaultRotation( xDiagram, 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..06e80bbb3 --- /dev/null +++ b/chart2/source/model/template/PieChartTypeTemplate.hxx @@ -0,0 +1,106 @@ +/* -*- 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 . + */ +#pragma once + +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> + +#include <ChartTypeTemplate.hxx> +#include <com/sun/star/chart2/PieChartOffsetMode.hpp> + +namespace chart +{ + +class PieChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ ChartTypeTemplate ____ + virtual bool matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void resetStyles2( + const rtl::Reference< ::chart::Diagram >& xDiagram ) override; + + // ____ ChartTypeTemplate ____ + virtual sal_Int32 getDimension() const override; + + virtual void adaptDiagram( + const rtl::Reference< ::chart::Diagram > & xDiagram ) override; + + virtual sal_Int32 getAxisCountByDimension( sal_Int32 nDimension ) override; + + virtual void adaptAxes( + const std::vector< rtl::Reference< ::chart::BaseCoordinateSystem > > & rCoordSys ) override; + + virtual void adaptScales( + const std::vector< rtl::Reference< ::chart::BaseCoordinateSystem > > & aCooSysSeq, + const css::uno::Reference< css::chart2::data::XLabeledDataSequence > & xCategories ) override; + + virtual void createChartTypes( + const std::vector< + std::vector< + rtl::Reference< + ::chart::DataSeries > > >& aSeriesSeq, + const std::vector< + rtl::Reference< + ::chart::BaseCoordinateSystem > > & rCoordSys, + const std::vector< rtl::Reference< ChartType > > & aOldChartTypesSeq + ) override; + + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; +}; + +} // namespace chart + +/* 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..cee026913 --- /dev/null +++ b/chart2/source/model/template/ScatterChartType.cxx @@ -0,0 +1,221 @@ +/* -*- 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 <Axis.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 +}; + +::chart::tPropertyValueMap& StaticScatterChartTypeDefaults() +{ + static ::chart::tPropertyValueMap aStaticDefaults = + []() + { + ::chart::tPropertyValueMap aOutMap; + ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_SCATTERCHARTTYPE_CURVE_STYLE, chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, 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 >( aOutMap, PROP_SCATTERCHARTTYPE_SPLINE_ORDER, 3 ); + return aOutMap; + }(); + return aStaticDefaults; +} + +::cppu::OPropertyArrayHelper& StaticScatterChartTypeInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper( + []() + { + std::vector< css::beans::Property > aProperties { + { CHART_UNONAME_CURVE_STYLE, + PROP_SCATTERCHARTTYPE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_CURVE_RESOLUTION, + PROP_SCATTERCHARTTYPE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_SPLINE_ORDER, + PROP_SCATTERCHARTTYPE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT } }; + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + return comphelper::containerToSequence( aProperties ); + }() ); + return aPropHelper; +} + +const uno::Reference< beans::XPropertySetInfo >& StaticScatterChartTypeInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(StaticScatterChartTypeInfoHelper() ) ); + return xPropertySetInfo; +} + +} // 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 )); +} + +rtl::Reference< ChartType > ScatterChartType::cloneChartType() const +{ + return new ScatterChartType( *this ); +} + +// ____ XChartType ____ +rtl::Reference< ::chart::BaseCoordinateSystem > + ScatterChartType::createCoordinateSystem2( sal_Int32 DimensionCount ) +{ + rtl::Reference< CartesianCoordinateSystem > xResult = + new CartesianCoordinateSystem( DimensionCount ); + + for( sal_Int32 i=0; i<DimensionCount; ++i ) + { + rtl::Reference< Axis > xAxis = xResult->getAxisByDimension2( 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() +{ + return { "label", "values-x", "values-y" }; +} + +// ____ OPropertySet ____ +void ScatterChartType::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = StaticScatterChartTypeDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +// ____ OPropertySet ____ +::cppu::IPropertyArrayHelper & SAL_CALL ScatterChartType::getInfoHelper() +{ + return StaticScatterChartTypeInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ScatterChartType::getPropertySetInfo() +{ + return StaticScatterChartTypeInfo(); +} + +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..f490c108c --- /dev/null +++ b/chart2/source/model/template/ScatterChartType.hxx @@ -0,0 +1,68 @@ +/* -*- 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 . + */ +#pragma once + +#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; + + virtual rtl::Reference<ChartType> cloneChartType() const override; + +private: + explicit ScatterChartType( const ScatterChartType & rOther ); + + // ____ XChartType ____ + virtual OUString SAL_CALL getChartType() override; + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedMandatoryRoles() override; + + // ____ OPropertySet ____ + virtual void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) 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; + + virtual rtl::Reference< ::chart::BaseCoordinateSystem > + createCoordinateSystem2( sal_Int32 DimensionCount ) override; +}; + +} // namespace chart + +/* 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..91fe7bba5 --- /dev/null +++ b/chart2/source/model/template/ScatterChartTypeTemplate.cxx @@ -0,0 +1,345 @@ +/* -*- 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 "ScatterChartType.hxx" +#include "XYDataInterpreter.hxx" +#include <ChartType.hxx> +#include <Diagram.hxx> +#include <DiagramHelper.hxx> +#include <DataSeries.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 <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 + +}; + +const ::chart::tPropertyValueMap& StaticScatterChartTypeTemplateDefaults() +{ + static const ::chart::tPropertyValueMap aStaticDefaults = + []() + { + ::chart::tPropertyValueMap aOutMap; + ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, chart2::CurveStyle_LINES ); + ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, 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 >( aOutMap, PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER, 3 ); + return aOutMap; + }(); + return aStaticDefaults; +} + + +::cppu::OPropertyArrayHelper& StaticScatterChartTypeTemplateInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper( + []() + { + std::vector< css::beans::Property > aProperties { + { CHART_UNONAME_CURVE_STYLE, + PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE, + cppu::UnoType<chart2::CurveStyle>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_CURVE_RESOLUTION, + PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT }, + { CHART_UNONAME_SPLINE_ORDER, + PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER, + cppu::UnoType<sal_Int32>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT } }; + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + return comphelper::containerToSequence( aProperties ); + }() ); + return aPropHelper; +} + +const uno::Reference< beans::XPropertySetInfo >& StaticScatterChartTypeTemplateInfo() +{ + static const uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(StaticScatterChartTypeTemplateInfoHelper() ) ); + return xPropertySetInfo; +} + +} // 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 ____ +void ScatterChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = StaticScatterChartTypeTemplateDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL ScatterChartTypeTemplate::getInfoHelper() +{ + return StaticScatterChartTypeTemplateInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL ScatterChartTypeTemplate::getPropertySetInfo() +{ + return StaticScatterChartTypeTemplateInfo(); +} + +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 ScatterChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + + try + { + DataSeriesHelper::switchSymbolsOnOrOff( xSeries, m_bHasSymbols, nSeriesIndex ); + DataSeriesHelper::switchLinesOnOrOff( xSeries, m_bHasLines ); + DataSeriesHelper::makeLinesThickOrThin( xSeries, 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; +} + +bool ScatterChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) +{ + bool bResult = ChartTypeTemplate::matchesTemplate2( 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< rtl::Reference< DataSeries > > aSeriesVec = + DiagramHelper::getDataSeriesFromDiagram( xDiagram ); + + for (auto const& series : aSeriesVec) + { + try + { + chart2::Symbol aSymbProp; + drawing::LineStyle eLineStyle; + + bool bCurrentHasSymbol = (series->getPropertyValue( "Symbol") >>= aSymbProp) && + (aSymbProp.Style != chart2::SymbolStyle_NONE); + + if( bCurrentHasSymbol ) + bSymbolFound = true; + + if( bCurrentHasSymbol && (!m_bHasSymbols) ) + { + bResult = false; + break; + } + + bool bCurrentHasLine = (series->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 + { + rtl::Reference< ChartType > xChartTypeProp = + DiagramHelper::getChartTypeByIndex( xDiagram, 0 ); + 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; +} + +rtl::Reference< ChartType > ScatterChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new ScatterChartType(); + + xResult->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE )); + xResult->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xResult->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +rtl::Reference< ChartType > ScatterChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new ScatterChartType(); + + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + + xResult->setPropertyValue( + CHART_UNONAME_CURVE_STYLE, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_STYLE )); + xResult->setPropertyValue( + CHART_UNONAME_CURVE_RESOLUTION, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_CURVE_RESOLUTION )); + xResult->setPropertyValue( + CHART_UNONAME_SPLINE_ORDER, getFastPropertyValue( PROP_SCATTERCHARTTYPE_TEMPLATE_SPLINE_ORDER )); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +rtl::Reference< DataInterpreter > ScatterChartTypeTemplate::getDataInterpreter2() +{ + 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..88441b844 --- /dev/null +++ b/chart2/source/model/template/ScatterChartTypeTemplate.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 . + */ +#pragma once + +#include <ChartTypeTemplate.hxx> +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class ScatterChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ ChartTypeTemplate ____ + virtual sal_Bool SAL_CALL supportsCategories() override; + virtual bool matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual rtl::Reference< ::chart::DataInterpreter > getDataInterpreter2() override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeGroupIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + + // ____ ChartTypeTemplate ____ + virtual rtl::Reference< ::chart::ChartType > + 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 + +/* 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..bd14ac3c4 --- /dev/null +++ b/chart2/source/model/template/StockChartTypeTemplate.cxx @@ -0,0 +1,435 @@ +/* -*- 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 "ColumnChartType.hxx" +#include "CandleStickChartType.hxx" +#include "LineChartType.hxx" +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include "StockDataInterpreter.hxx" +#include <DiagramHelper.hxx> +#include <Diagram.hxx> +#include <BaseCoordinateSystem.hxx> +#include <servicenames_charttypes.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <PropertyHelper.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <tools/diagnose_ex.h> + +#include <algorithm> +#include <cstddef> + +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 ); +} + +::chart::tPropertyValueMap& GetStaticStockChartTypeTemplateDefaults() +{ + static ::chart::tPropertyValueMap aStaticDefaults = + [](){ + ::chart::tPropertyValueMap aTmp; + ::chart::PropertyHelper::setPropertyValueDefault( aTmp, PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME, false ); + ::chart::PropertyHelper::setPropertyValueDefault( aTmp, PROP_STOCKCHARTTYPE_TEMPLATE_OPEN, false ); + ::chart::PropertyHelper::setPropertyValueDefault( aTmp, PROP_STOCKCHARTTYPE_TEMPLATE_LOW_HIGH, true ); + ::chart::PropertyHelper::setPropertyValueDefault( aTmp, PROP_STOCKCHARTTYPE_TEMPLATE_JAPANESE, false ); + return aTmp; + }(); + return aStaticDefaults; +}; + +::cppu::OPropertyArrayHelper& GetStaticStockChartTypeTemplateInfoHelper() +{ + static ::cppu::OPropertyArrayHelper aPropHelper = + [](){ + std::vector< css::beans::Property > aProperties; + lcl_AddPropertiesToVector( aProperties ); + + std::sort( aProperties.begin(), aProperties.end(), + ::chart::PropertyNameLess() ); + + return comphelper::containerToSequence( aProperties ); + }(); + return aPropHelper; +}; + + +uno::Reference< beans::XPropertySetInfo >& GetStaticStockChartTypeTemplateInfo() +{ + static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( + ::cppu::OPropertySetHelper::createPropertySetInfo(GetStaticStockChartTypeTemplateInfoHelper() ) ); + return xPropertySetInfo; +}; + +} // 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 ____ +void StockChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const +{ + const tPropertyValueMap& rStaticDefaults = GetStaticStockChartTypeTemplateDefaults(); + tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); + if( aFound == rStaticDefaults.end() ) + rAny.clear(); + else + rAny = (*aFound).second; +} + +::cppu::IPropertyArrayHelper & SAL_CALL StockChartTypeTemplate::getInfoHelper() +{ + return GetStaticStockChartTypeTemplateInfoHelper(); +} + +// ____ XPropertySet ____ +uno::Reference< beans::XPropertySetInfo > SAL_CALL StockChartTypeTemplate::getPropertySetInfo() +{ + return GetStaticStockChartTypeTemplateInfo(); +} + +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 StockChartTypeTemplate::applyStyle2( + const rtl::Reference< DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) +{ + ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + try + { + sal_Int32 nNewAxisIndex = 0; + + bool bHasVolume = false; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME ) >>= bHasVolume; + if( bHasVolume && nChartTypeIndex != 0 ) + nNewAxisIndex = 1; + + xSeries->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 + drawing::LineStyle eStyle = drawing::LineStyle_NONE; + xSeries->getPropertyValue( "LineStyle" ) >>= eStyle; + if( eStyle == drawing::LineStyle_NONE ) + xSeries->setPropertyValue( "LineStyle", uno::Any( drawing::LineStyle_SOLID )); + } + + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void StockChartTypeTemplate::resetStyles2( + const rtl::Reference< ::chart::Diagram >& xDiagram ) +{ + ChartTypeTemplate::resetStyles2( xDiagram ); + if( getDimension() == 3 ) + { + std::vector< rtl::Reference< DataSeries > > aSeriesVec = + DiagramHelper::getDataSeriesFromDiagram( xDiagram ); + for (auto const& series : aSeriesVec) + { + series->setPropertyValue( "AttachedAxisIndex", uno::Any( sal_Int32(0) ) ); + } + } + + DiagramHelper::setVertical( xDiagram, false ); +} + +rtl::Reference< ChartType > StockChartTypeTemplate::getChartTypeForIndex( sal_Int32 nChartTypeIndex ) +{ + rtl::Reference< ChartType > xCT; + bool bHasVolume = false; + getFastPropertyValue( PROP_STOCKCHARTTYPE_TEMPLATE_VOLUME ) >>= bHasVolume; + if( bHasVolume ) + { + if( nChartTypeIndex == 0 ) + xCT = new ColumnChartType(); + else if( nChartTypeIndex == 1 ) + xCT = new CandleStickChartType(); + else + xCT = new LineChartType(); + } + else + { + if( nChartTypeIndex == 0 ) + xCT = new CandleStickChartType(); + else + xCT = new LineChartType(); + } + return xCT; +} + +void StockChartTypeTemplate::createChartTypes( + const std::vector< std::vector< rtl::Reference< DataSeries > > > & aSeriesSeq, + const std::vector< rtl::Reference< BaseCoordinateSystem > > & rCoordSys, + const std::vector< rtl::Reference< ChartType > >& /* aOldChartTypesSeq */ ) +{ + if( rCoordSys.empty() ) + return; + + try + { + 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; + + std::size_t nSeriesIndex = 0; + + std::vector< rtl::Reference< ChartType > > aChartTypeVec; + // Bars (Volume) + if( bHasVolume ) + { + // chart type + rtl::Reference< ChartType > xCT = new ColumnChartType(); + aChartTypeVec.push_back( xCT ); + + if( aSeriesSeq.size() > nSeriesIndex && + !aSeriesSeq[nSeriesIndex].empty() ) + { + xCT->setDataSeries( aSeriesSeq[ nSeriesIndex ] ); + } + ++nSeriesIndex; + } + + rtl::Reference< ChartType > xCT = new CandleStickChartType(); + aChartTypeVec.push_back( xCT ); + + xCT->setPropertyValue( "Japanese", uno::Any( bJapaneseStyle )); + xCT->setPropertyValue( "ShowFirst", uno::Any( bShowFirst )); + xCT->setPropertyValue( "ShowHighLow", uno::Any( bShowHighLow )); + + if( aSeriesSeq.size() > nSeriesIndex && + !aSeriesSeq[ nSeriesIndex ].empty() ) + { + xCT->setDataSeries( aSeriesSeq[ nSeriesIndex ] ); + } + ++nSeriesIndex; + + // Lines (remaining series) + if( aSeriesSeq.size() > nSeriesIndex && + !aSeriesSeq[ nSeriesIndex ].empty() ) + { + xCT = new LineChartType(); + aChartTypeVec.push_back( xCT ); + + xCT->setDataSeries( aSeriesSeq[ nSeriesIndex ] ); + } + + rCoordSys[ 0 ]->setChartTypes( aChartTypeVec ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +// ____ ChartTypeTemplate ____ +bool StockChartTypeTemplate::matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + 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; + + rtl::Reference< ChartType > xVolumeChartType; + rtl::Reference< ChartType > xCandleStickChartType; + rtl::Reference< ChartType > xLineChartType; + sal_Int32 nNumberOfChartTypes = 0; + + for( rtl::Reference< BaseCoordinateSystem > const & coords : xDiagram->getBaseCoordinateSystems() ) + { + for( rtl::Reference< ChartType > const & chartType : coords->getChartTypes2() ) + { + ++nNumberOfChartTypes; + if( nNumberOfChartTypes > 3 ) + break; + OUString aCTService = chartType->getChartType(); + if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN ) + xVolumeChartType = chartType; + else if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ) + xCandleStickChartType = chartType; + else if( aCTService == CHART2_SERVICE_NAME_CHARTTYPE_LINE ) + xLineChartType = chartType; + } + if( nNumberOfChartTypes > 3 ) + break; + } + + if (xCandleStickChartType.is() && bHasVolume == xVolumeChartType.is()) + { + bResult = true; + + // check for japanese style + bool bJapaneseProp = false; + xCandleStickChartType->getPropertyValue( "Japanese") >>= bJapaneseProp; + bResult = bResult && ( bHasJapaneseStyle == bJapaneseProp ); + + // in old chart japanese == showFirst + bool bShowFirstProp = false; + xCandleStickChartType->getPropertyValue( "ShowFirst") >>= bShowFirstProp; + bResult = bResult && ( bHasOpenValue == bShowFirstProp ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return bResult; +} + +rtl::Reference< ChartType > StockChartTypeTemplate::getChartTypeForNewSeries2( + const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes ) +{ + rtl::Reference< ChartType > xResult; + + try + { + xResult = new LineChartType(); + ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +rtl::Reference< DataInterpreter > StockChartTypeTemplate::getDataInterpreter2() +{ + 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..78d6c02e1 --- /dev/null +++ b/chart2/source/model/template/StockChartTypeTemplate.hxx @@ -0,0 +1,113 @@ +/* -*- 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 . + */ +#pragma once + +#include <ChartTypeTemplate.hxx> +#include <OPropertySet.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/uno3.hxx> + +namespace chart +{ + +class StockChartTypeTemplate : + public cppu::BaseMutex, + 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 void GetDefaultValue( sal_Int32 nHandle, css::uno::Any& rAny ) const override; + virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper() override; + + // ____ XPropertySet ____ + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() override; + + // ____ XChartTypeTemplate ____ + virtual bool matchesTemplate2( + const rtl::Reference< ::chart::Diagram >& xDiagram, + bool bAdaptProperties ) override; + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForNewSeries2( const std::vector< + rtl::Reference< ::chart::ChartType > >& aFormerlyUsedChartTypes ) override; + virtual rtl::Reference< ::chart::DataInterpreter > getDataInterpreter2() override; + virtual void applyStyle2( + const rtl::Reference< ::chart::DataSeries >& xSeries, + ::sal_Int32 nChartTypeIndex, + ::sal_Int32 nSeriesIndex, + ::sal_Int32 nSeriesCount ) override; + virtual void resetStyles2( + const rtl::Reference< ::chart::Diagram >& xDiagram ) override; + + // ChartTypeTemplate + virtual sal_Int32 getAxisCountByDimension( sal_Int32 nDimension ) override; + + // ____ ChartTypeTemplate ____ + virtual void createChartTypes( + const std::vector< + std::vector< + rtl::Reference< + ::chart::DataSeries > > >& aSeriesSeq, + const std::vector< + rtl::Reference< + ::chart::BaseCoordinateSystem > > & rCoordSys, + const std::vector< rtl::Reference< ChartType > > & aOldChartTypesSeq + ) override; + + virtual rtl::Reference< ::chart::ChartType > + getChartTypeForIndex( sal_Int32 nChartTypeIndex ) override; + +private: + // todo: deprecate this variable + StockVariant m_eStockVariant; +}; + +} // namespace chart + +/* 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..24072f718 --- /dev/null +++ b/chart2/source/model/template/StockDataInterpreter.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 <sal/config.h> + +#include <cstddef> + +#include "StockDataInterpreter.hxx" +#include "StockChartTypeTemplate.hxx" +#include <DataSeries.hxx> +#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 ) : + m_eStockVariant( eVariant ) +{} + +StockDataInterpreter::~StockDataInterpreter() +{} + +// ____ XDataInterpreter ____ +InterpretedData StockDataInterpreter::interpretDataSource( + const Reference< data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& rArguments, + const std::vector< rtl::Reference< ::chart::DataSeries > >& rSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + + uno::Reference< chart2::data::XLabeledDataSequence > xCategories; + std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aData = DataInterpreter::getDataSequences(xSource); + const sal_Int32 nDataCount( aData.size()); + + // 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 + std::vector< std::vector< std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > > > aSequences( nNumberOfGroups ); + const sal_Int32 nBarGroupIndex( 0 ); + const sal_Int32 nCandleStickGroupIndex( nNumberOfGroups - 1 ); + + // allocate space for labeled sequences + if( nRemaining > 0 ) + ++nCandleStickSeries; + aSequences[nCandleStickGroupIndex].resize( nCandleStickSeries ); + auto & pCandleStickGroup = aSequences[nCandleStickGroupIndex]; + 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].resize( nVolumeSeries ); + } + auto & pBarGroup = aSequences[nBarGroupIndex]; + + // create data + sal_Int32 nSourceIndex = 0; // index into aData sequence + + // 1. categories + if( bHasCategories ) + { + xCategories = aData[nSourceIndex]; + ++nSourceIndex; + } + + // 2. create "full" series + for( sal_Int32 nLabeledSeqIdx=0; nLabeledSeqIdx<nNumOfFullSeries; ++nLabeledSeqIdx ) + { + // bar + if( bHasVolume ) + { + pBarGroup[nLabeledSeqIdx].resize( 1 ); + pBarGroup[nLabeledSeqIdx][0] = aData[nSourceIndex]; + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-y"); + ++nSourceIndex; + } + + sal_Int32 nSeqIdx = 0; + if( bHasOpenValues ) + { + pCandleStickGroup[nLabeledSeqIdx].resize( 4 ); + pCandleStickGroup[nLabeledSeqIdx][nSeqIdx] = aData[nSourceIndex]; + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-first"); + ++nSourceIndex; + ++nSeqIdx; + } + else + pCandleStickGroup[nLabeledSeqIdx].resize( 3 ); + auto & pLabeledSeq = pCandleStickGroup[nLabeledSeqIdx]; + + pLabeledSeq[nSeqIdx] = aData[nSourceIndex]; + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-min"); + ++nSourceIndex; + ++nSeqIdx; + + pLabeledSeq[nSeqIdx] = aData[nSourceIndex]; + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-max"); + ++nSourceIndex; + ++nSeqIdx; + + pLabeledSeq[nSeqIdx] = 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 ); + pBarGroup[nVolumeSeries - 1].resize( 1 ); + OSL_ASSERT( nDataCount > nSourceIndex ); + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-y"); + pBarGroup[nVolumeSeries - 1][0] = 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; + pCandleStickGroup[nSeriesIndex].resize( nRemaining ); + auto & pLabeledSeq = pCandleStickGroup[nSeriesIndex]; + OSL_ASSERT( nDataCount > nSourceIndex ); + + // 1. low + sal_Int32 nSeqIdx( 0 ); + pLabeledSeq[nSeqIdx] = aData[nSourceIndex]; + if( aData[nSourceIndex].is()) + SetRole( aData[nSourceIndex]->getValues(), "values-min"); + ++nSourceIndex; + ++nSeqIdx; + + // 2. high + if( nSeqIdx < nRemaining ) + { + pLabeledSeq[nSeqIdx] = 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 ) + { + pLabeledSeq[nSeqIdx] = 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 + std::vector< std::vector< rtl::Reference< DataSeries > > > aResultSeries( nNumberOfGroups ); + sal_Int32 nGroupIndex; + std::size_t nReUsedSeriesIdx = 0; + for( nGroupIndex=0; nGroupIndex<nNumberOfGroups; ++nGroupIndex ) + { + const sal_Int32 nNumSeriesData = aSequences[nGroupIndex].size(); + aResultSeries[nGroupIndex].resize( nNumSeriesData ); + auto & pResultSerie = aResultSeries[nGroupIndex]; + for( sal_Int32 nSeriesIdx = 0; nSeriesIdx < nNumSeriesData; ++nSeriesIdx, ++nReUsedSeriesIdx ) + { + try + { + rtl::Reference< DataSeries > xSeries; + if( nReUsedSeriesIdx < rSeriesToReUse.size()) + xSeries = rSeriesToReUse[nReUsedSeriesIdx]; + else + xSeries = new DataSeries; + assert( xSeries.is() ); + xSeries->setData( aSequences[nGroupIndex][nSeriesIdx] ); + pResultSerie[nSeriesIdx] = xSeries; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + + return { 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) +bool StockDataInterpreter::isDataCompatible( + const InterpretedData& aInterpretedData ) +{ + // high/low/close + std::size_t 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.size() < (bHasVolume ? 2U : 1U )) + return false; + + // 2. a. volume -- use default check + if( bHasVolume ) + { + if( ! DataInterpreter::isDataCompatible( + { std::vector< std::vector< rtl::Reference< DataSeries > > >{ + aInterpretedData.Series[0] }, + aInterpretedData.Categories })) + return false; + } + + // 2. b. candlestick + { + OSL_ASSERT( aInterpretedData.Series.size() > (bHasVolume ? 1U : 0U)); + const std::vector< rtl::Reference< DataSeries > > & aSeries = aInterpretedData.Series[(bHasVolume ? 1 : 0)]; + if(aSeries.empty()) + return false; + for( rtl::Reference< DataSeries > const & dataSeries : aSeries ) + { + try + { + if( dataSeries->getDataSequences2().size() != nNumberOfNecessarySequences ) + return false; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + + // 2. c. additional series + // ignore + + return true; +} + +InterpretedData StockDataInterpreter::reinterpretDataSeries( + const InterpretedData& aInterpretedData ) +{ + // prerequisite: StockDataInterpreter::isDataCompatible() returned true + return aInterpretedData; +} + +uno::Any StockDataInterpreter::getChartTypeSpecificData( + const OUString& sKey ) +{ + if( sKey == "stock variant" ) + { + StockChartTypeTemplate::StockVariant eStockVariant( GetStockVariant()); + std::map< StockChartTypeTemplate::StockVariant, sal_Int32 > aTranslation { + { StockChartTypeTemplate::StockVariant::NONE, 0 }, + { StockChartTypeTemplate::StockVariant::Open, 1 }, + { StockChartTypeTemplate::StockVariant::Volume, 2 }, + { StockChartTypeTemplate::StockVariant::VolumeOpen, 3 } + }; + return uno::Any( aTranslation[eStockVariant] ); + } + return uno::Any(); +} + +} // 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..4617da597 --- /dev/null +++ b/chart2/source/model/template/StockDataInterpreter.hxx @@ -0,0 +1,56 @@ +/* -*- 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 . + */ +#pragma once + +#include <DataInterpreter.hxx> + +#include "StockChartTypeTemplate.hxx" + +namespace chart +{ + +class StockDataInterpreter : public DataInterpreter +{ +public: + explicit StockDataInterpreter( + StockChartTypeTemplate::StockVariant eVariant ); + virtual ~StockDataInterpreter() override; + +protected: + // ____ XDataInterpreter ____ + virtual InterpretedData interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const std::vector< rtl::Reference< ::chart::DataSeries > >& aSeriesToReUse ) override; + virtual bool isDataCompatible( + const InterpretedData& aInterpretedData ) override; + virtual InterpretedData reinterpretDataSeries( + const InterpretedData& aInterpretedData ) override; + virtual css::uno::Any getChartTypeSpecificData( + const OUString& sKey ) override; + +private: + StockChartTypeTemplate::StockVariant m_eStockVariant; + + StockChartTypeTemplate::StockVariant GetStockVariant() const { return m_eStockVariant;} +}; + +} // namespace chart + +/* 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..d77a3df39 --- /dev/null +++ b/chart2/source/model/template/XYDataInterpreter.cxx @@ -0,0 +1,243 @@ +/* -*- 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 <sal/config.h> + +#include <cstddef> + +#include "XYDataInterpreter.hxx" +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <CommonConverters.hxx> +#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() +{ +} + +XYDataInterpreter::~XYDataInterpreter() +{ +} + +// ____ XDataInterpreter ____ +InterpretedData XYDataInterpreter::interpretDataSource( + const Reference< chart2::data::XDataSource >& xSource, + const Sequence< beans::PropertyValue >& aArguments, + const std::vector< rtl::Reference< DataSeries > >& aSeriesToReUse ) +{ + if( ! xSource.is()) + return InterpretedData(); + + std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aData = DataInterpreter::getDataSequences(xSource); + + uno::Reference< chart2::data::XLabeledDataSequence > xValuesX; + vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSequencesVec; + + uno::Reference< chart2::data::XLabeledDataSequence > xCategories; + bool bHasCategories = HasCategories( aArguments, aData ); + bool bUseCategoriesAsX = UseCategoriesAsX( aArguments ); + + // parse data + bool bCategoriesUsed = false; + bool bSetXValues = aData.size()>1; + for( uno::Reference< chart2::data::XLabeledDataSequence > const & labelData : aData ) + { + try + { + if( bHasCategories && ! bCategoriesUsed ) + { + xCategories = labelData; + if( xCategories.is()) + { + SetRole( xCategories->getValues(), "categories"); + if( bUseCategoriesAsX ) + bSetXValues = false; + } + bCategoriesUsed = true; + } + else if( !xValuesX.is() && bSetXValues ) + { + xValuesX = 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< rtl::Reference< DataSeries > > aSeriesVec; + aSeriesVec.reserve( aSequencesVec.size()); + + Reference< data::XLabeledDataSequence > xClonedXValues = xValuesX; + Reference< util::XCloneable > xCloneable( xValuesX, uno::UNO_QUERY ); + + std::size_t nSeriesIndex = 0; + for (auto const& elem : aSequencesVec) + { + vector< uno::Reference< chart2::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); + + rtl::Reference< DataSeries > xSeries; + if( nSeriesIndex < aSeriesToReUse.size()) + xSeries = aSeriesToReUse[nSeriesIndex]; + else + xSeries = new DataSeries; + assert( xSeries.is() ); + xSeries->setData( aNewData ); + + aSeriesVec.push_back( xSeries ); + ++nSeriesIndex; + } + + return { { aSeriesVec }, xCategories }; +} + +InterpretedData XYDataInterpreter::reinterpretDataSeries( + const InterpretedData& aInterpretedData ) +{ + InterpretedData aResult( aInterpretedData ); + + sal_Int32 i=0; + std::vector< rtl::Reference< DataSeries > > aSeries = FlattenSequence( aInterpretedData.Series ); + const sal_Int32 nCount = aSeries.size(); + for( ; i<nCount; ++i ) + { + try + { + std::vector< uno::Reference< data::XLabeledDataSequence > > aNewSequences; + + // values-y + uno::Reference< chart2::data::XLabeledDataSequence > xValuesY( + DataSeriesHelper::getDataSequenceByRole( aSeries[i], "values-y" )); + uno::Reference< chart2::data::XLabeledDataSequence > xValuesX( + DataSeriesHelper::getDataSequenceByRole( aSeries[i], "values-x" )); + // re-use values-... as values-x/values-y + if( ! xValuesX.is() || + ! xValuesY.is()) + { + vector< uno::Reference< chart2::data::XLabeledDataSequence > > aValueSeqVec( + DataSeriesHelper::getAllDataSequencesByRole( + aSeries[i]->getDataSequences2(), "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 = aValueSeqVec[nIndex++]; + if( xValuesY.is()) + SetRole( xValuesY->getValues(), "values-y"); + } + + if( ! xValuesX.is() && + aValueSeqVec.size() > nIndex ) + { + xValuesX = aValueSeqVec[nIndex++]; + if( xValuesX.is()) + SetRole( xValuesY->getValues(), "values-x"); + } + } + if( xValuesY.is()) + { + if( xValuesX.is()) + { + aNewSequences = { xValuesX, xValuesY }; + } + else + { + aNewSequences = { xValuesY }; + } + } + + const std::vector< uno::Reference< data::XLabeledDataSequence > > & aSeqs = aSeries[i]->getDataSequences2(); + if( aSeqs.size() != aNewSequences.size() ) + { +#ifdef DBG_UTIL + for( auto const & j : aSeqs ) + { + SAL_WARN_IF((j == xValuesY || j == xValuesX), "chart2.template", "All sequences should be used" ); + } +#endif + aSeries[i]->setData( aNewSequences ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + + return aResult; +} + +// criterion: all series must have exactly two data::XLabeledDataSequences +bool XYDataInterpreter::isDataCompatible( + const InterpretedData& aInterpretedData ) +{ + const std::vector< rtl::Reference< DataSeries > > aSeries = FlattenSequence( aInterpretedData.Series ); + for( rtl::Reference< DataSeries > const & dataSeries : aSeries ) + { + try + { + if( dataSeries->getDataSequences2().size() != 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..56343013d --- /dev/null +++ b/chart2/source/model/template/XYDataInterpreter.hxx @@ -0,0 +1,46 @@ +/* -*- 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 . + */ +#pragma once + +#include <DataInterpreter.hxx> + +namespace chart +{ + +class XYDataInterpreter : public DataInterpreter +{ +public: + explicit XYDataInterpreter(); + virtual ~XYDataInterpreter() override; + +protected: + // ____ DataInterpreter ____ + virtual InterpretedData interpretDataSource( + const css::uno::Reference< css::chart2::data::XDataSource >& xSource, + const css::uno::Sequence< css::beans::PropertyValue >& aArguments, + const std::vector< rtl::Reference< ::chart::DataSeries > >& aSeriesToReUse ) override; + virtual InterpretedData reinterpretDataSeries( + const InterpretedData& aInterpretedData ) override; + virtual bool isDataCompatible( + const InterpretedData& aInterpretedData ) override; +}; + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |