/* -*- 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 "WrappedSymbolProperties.hxx" #include "WrappedSeriesOrDiagramProperty.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; using ::com::sun::star::beans::Property; namespace chart::wrapper { namespace { class WrappedSymbolTypeProperty : public WrappedSeriesOrDiagramProperty< sal_Int32 > { public: virtual sal_Int32 getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const override; virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, const sal_Int32& aNewValue ) const override; virtual Any getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const override; virtual beans::PropertyState getPropertyState( const Reference< beans::XPropertyState >& xInnerPropertyState ) const override; explicit WrappedSymbolTypeProperty(const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType); }; class WrappedSymbolBitmapURLProperty : public WrappedSeriesOrDiagramProperty { public: virtual OUString getValueFromSeries(const Reference& xSeriesPropertySet) const override; virtual void setValueToSeries(const Reference & xSeriesPropertySet, OUString const & xNewGraphicURL) const override; explicit WrappedSymbolBitmapURLProperty(const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType); }; class WrappedSymbolBitmapProperty : public WrappedSeriesOrDiagramProperty> { public: virtual uno::Reference getValueFromSeries(const Reference& xSeriesPropertySet) const override; virtual void setValueToSeries(const Reference & xSeriesPropertySet, uno::Reference const & xNewGraphic) const override; explicit WrappedSymbolBitmapProperty(const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType); }; class WrappedSymbolSizeProperty : public WrappedSeriesOrDiagramProperty< awt::Size > { public: virtual awt::Size getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const override; virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, const awt::Size& aNewSize ) const override; virtual beans::PropertyState getPropertyState( const Reference< beans::XPropertyState >& xInnerPropertyState ) const override; explicit WrappedSymbolSizeProperty(const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType); }; class WrappedSymbolAndLinesProperty : public WrappedSeriesOrDiagramProperty< bool > { public: virtual bool getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const override; virtual void setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, const bool& bDrawLines ) const override; virtual beans::PropertyState getPropertyState( const Reference< beans::XPropertyState >& xInnerPropertyState ) const override; explicit WrappedSymbolAndLinesProperty(const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType); }; enum { //symbol properties PROP_CHART_SYMBOL_TYPE = FAST_PROPERTY_ID_START_CHART_SYMBOL_PROP, PROP_CHART_SYMBOL_BITMAP_URL, PROP_CHART_SYMBOL_BITMAP, PROP_CHART_SYMBOL_SIZE, PROP_CHART_SYMBOL_AND_LINES }; sal_Int32 lcl_getSymbolType( const css::chart2::Symbol& rSymbol ) { sal_Int32 nSymbol = css::chart::ChartSymbolType::NONE; switch( rSymbol.Style ) { case chart2::SymbolStyle_NONE: break; case chart2::SymbolStyle_AUTO: nSymbol = css::chart::ChartSymbolType::AUTO; break; case chart2::SymbolStyle_STANDARD: nSymbol = rSymbol.StandardSymbol%15; break; case chart2::SymbolStyle_POLYGON://new feature nSymbol = css::chart::ChartSymbolType::AUTO; break; case chart2::SymbolStyle_GRAPHIC: nSymbol = css::chart::ChartSymbolType::BITMAPURL; break; default: nSymbol = css::chart::ChartSymbolType::AUTO; break; } return nSymbol; } void lcl_setSymbolTypeToSymbol( sal_Int32 nSymbolType, chart2::Symbol& rSymbol ) { switch( nSymbolType ) { case css::chart::ChartSymbolType::NONE: rSymbol.Style = chart2::SymbolStyle_NONE; break; case css::chart::ChartSymbolType::AUTO: rSymbol.Style = chart2::SymbolStyle_AUTO; break; case css::chart::ChartSymbolType::BITMAPURL: rSymbol.Style = chart2::SymbolStyle_GRAPHIC; break; default: rSymbol.Style = chart2::SymbolStyle_STANDARD; rSymbol.StandardSymbol = nSymbolType; break; } } void lcl_addWrappedProperties( std::vector< std::unique_ptr >& rList , const std::shared_ptr< Chart2ModelContact >& spChart2ModelContact , tSeriesOrDiagramPropertyType ePropertyType ) { rList.emplace_back( new WrappedSymbolTypeProperty( spChart2ModelContact, ePropertyType ) ); rList.emplace_back( new WrappedSymbolBitmapURLProperty( spChart2ModelContact, ePropertyType ) ); rList.emplace_back( new WrappedSymbolBitmapProperty( spChart2ModelContact, ePropertyType ) ); rList.emplace_back( new WrappedSymbolSizeProperty( spChart2ModelContact, ePropertyType ) ); rList.emplace_back( new WrappedSymbolAndLinesProperty( spChart2ModelContact, ePropertyType ) ); } }//anonymous namespace void WrappedSymbolProperties::addProperties( std::vector< Property > & rOutProperties ) { rOutProperties.emplace_back( "SymbolType", PROP_CHART_SYMBOL_TYPE, cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); rOutProperties.emplace_back( "SymbolBitmapURL", PROP_CHART_SYMBOL_BITMAP_URL, cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); rOutProperties.emplace_back( "SymbolBitmap", PROP_CHART_SYMBOL_BITMAP, cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); rOutProperties.emplace_back( "SymbolSize", PROP_CHART_SYMBOL_SIZE, cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); rOutProperties.emplace_back( "Lines", PROP_CHART_SYMBOL_AND_LINES, cppu::UnoType::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); } void WrappedSymbolProperties::addWrappedPropertiesForSeries( std::vector< std::unique_ptr >& rList , const std::shared_ptr< Chart2ModelContact >& spChart2ModelContact ) { lcl_addWrappedProperties( rList, spChart2ModelContact, DATA_SERIES ); } void WrappedSymbolProperties::addWrappedPropertiesForDiagram( std::vector< std::unique_ptr >& rList , const std::shared_ptr< Chart2ModelContact >& spChart2ModelContact ) { lcl_addWrappedProperties( rList, spChart2ModelContact, DIAGRAM ); } WrappedSymbolTypeProperty::WrappedSymbolTypeProperty( const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType ) : WrappedSeriesOrDiagramProperty< sal_Int32 >( u"SymbolType"_ustr , uno::Any( css::chart::ChartSymbolType::NONE ) , spChart2ModelContact , ePropertyType ) { } sal_Int32 WrappedSymbolTypeProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const { sal_Int32 aRet = 0; m_aDefaultValue >>= aRet; chart2::Symbol aSymbol; if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol ) ) aRet = lcl_getSymbolType( aSymbol ); return aRet; } void WrappedSymbolTypeProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, const sal_Int32& nSymbolType ) const { if(!xSeriesPropertySet.is()) return; chart2::Symbol aSymbol; xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol; lcl_setSymbolTypeToSymbol( nSymbolType, aSymbol ); xSeriesPropertySet->setPropertyValue( u"Symbol"_ustr, uno::Any( aSymbol ) ); } Any WrappedSymbolTypeProperty::getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const { //the old chart (< OOo 2.3) needs symbol-type="automatic" at the plot-area if any of the series should be able to have symbols if( m_ePropertyType == DIAGRAM ) { bool bHasAmbiguousValue = false; sal_Int32 aValue = 0; if( detectInnerValue( aValue, bHasAmbiguousValue ) ) { if(bHasAmbiguousValue) { m_aOuterValue <<= css::chart::ChartSymbolType::AUTO; } else { if( aValue == css::chart::ChartSymbolType::NONE ) m_aOuterValue <<= css::chart::ChartSymbolType::NONE; else m_aOuterValue <<= css::chart::ChartSymbolType::AUTO; } } return m_aOuterValue; } else { css::uno::Any aRet( m_aDefaultValue ); aRet <<= getValueFromSeries( xInnerPropertySet ); return aRet; } } beans::PropertyState WrappedSymbolTypeProperty::getPropertyState( const Reference< beans::XPropertyState >& xInnerPropertyState ) const { //the special situation for this property here is that the diagram default can be //different from the normal default and different from all singles series values //so we need to return PropertyState_DIRECT_VALUE for more cases if( m_ePropertyType == DATA_SERIES && //single series or point m_spChart2ModelContact) { rtl::Reference< ::chart::Diagram > xDiagram( m_spChart2ModelContact->getDiagram() ); rtl::Reference< ::chart::DataSeries > xSeries( dynamic_cast(xInnerPropertyState.get()) ); rtl::Reference< ChartType > xChartType( xDiagram->getChartTypeOfSeries( xSeries ) ); if( ChartTypeHelper::isSupportingSymbolProperties( xChartType, 2 ) ) return beans::PropertyState_DIRECT_VALUE; } return WrappedProperty::getPropertyState( xInnerPropertyState ); } WrappedSymbolBitmapURLProperty::WrappedSymbolBitmapURLProperty( const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType ) : WrappedSeriesOrDiagramProperty(u"SymbolBitmapURL"_ustr, uno::Any(OUString()), spChart2ModelContact, ePropertyType) { } OUString WrappedSymbolBitmapURLProperty::getValueFromSeries(const Reference< beans::XPropertySet >& /*xSeriesPropertySet*/) const { return OUString(); } void WrappedSymbolBitmapURLProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, OUString const & xNewGraphicURL) const { if (!xSeriesPropertySet.is()) return; chart2::Symbol aSymbol; if (xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol) { if (!xNewGraphicURL.isEmpty()) { Graphic aGraphic = vcl::graphic::loadFromURL(xNewGraphicURL); aSymbol.Graphic.set(aGraphic.GetXGraphic()); xSeriesPropertySet->setPropertyValue(u"Symbol"_ustr, uno::Any(aSymbol)); } } } WrappedSymbolBitmapProperty::WrappedSymbolBitmapProperty( const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType ) : WrappedSeriesOrDiagramProperty>(u"SymbolBitmap"_ustr, uno::Any(uno::Reference()), spChart2ModelContact, ePropertyType) { } uno::Reference WrappedSymbolBitmapProperty::getValueFromSeries(const Reference< beans::XPropertySet >& xSeriesPropertySet) const { uno::Reference xGraphic; m_aDefaultValue >>= xGraphic; chart2::Symbol aSymbol; if (xSeriesPropertySet.is() && (xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol) && aSymbol.Graphic.is()) { xGraphic = aSymbol.Graphic; } return xGraphic; } void WrappedSymbolBitmapProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, uno::Reference const & xNewGraphic) const { if (!xSeriesPropertySet.is()) return; chart2::Symbol aSymbol; if (xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol) { if (xNewGraphic.is()) { aSymbol.Graphic.set(xNewGraphic); xSeriesPropertySet->setPropertyValue(u"Symbol"_ustr, uno::Any(aSymbol)); } } } namespace { void lcl_correctSymbolSizeForBitmaps( chart2::Symbol& rSymbol ) { if( rSymbol.Style != chart2::SymbolStyle_GRAPHIC ) return; if( rSymbol.Size.Width != -1 ) return; if( rSymbol.Size.Height != -1 ) return; //find a good automatic size try { const awt::Size aDefaultSize(250,250); awt::Size aSize = aDefaultSize; uno::Reference< beans::XPropertySet > xProp( rSymbol.Graphic, uno::UNO_QUERY ); if( xProp.is() ) { bool bFoundSize = false; try { if( xProp->getPropertyValue( u"Size100thMM"_ustr ) >>= aSize ) { if( aSize.Width == 0 && aSize.Height == 0 ) aSize = aDefaultSize; else bFoundSize = true; } } catch( const uno::Exception& ) { TOOLS_WARN_EXCEPTION("chart2", "" ); } if(!bFoundSize) { awt::Size aAWTPixelSize(10,10); if( xProp->getPropertyValue( u"SizePixel"_ustr ) >>= aAWTPixelSize ) { Size aPixelSize(aAWTPixelSize.Width,aAWTPixelSize.Height); Size aNewSize = o3tl::convert(aPixelSize, o3tl::Length::pt, o3tl::Length::mm100); aSize = awt::Size( aNewSize.Width(), aNewSize.Height() ); if( aSize.Width == 0 && aSize.Height == 0 ) aSize = aDefaultSize; } } } rSymbol.Size = aSize; } catch( const uno::Exception& ) { TOOLS_WARN_EXCEPTION("chart2", "" ); } } }//end anonymous namespace WrappedSymbolSizeProperty::WrappedSymbolSizeProperty( const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType ) : WrappedSeriesOrDiagramProperty< awt::Size >( u"SymbolSize"_ustr , uno::Any( awt::Size(250,250) ), spChart2ModelContact, ePropertyType ) { } awt::Size WrappedSymbolSizeProperty::getValueFromSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet ) const { awt::Size aRet; m_aDefaultValue >>= aRet; chart2::Symbol aSymbol; if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol )) aRet = aSymbol.Size; return aRet; } void WrappedSymbolSizeProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, const awt::Size& aNewSize ) const { if(!xSeriesPropertySet.is()) return; chart2::Symbol aSymbol; if( xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol ) { aSymbol.Size = aNewSize; lcl_correctSymbolSizeForBitmaps(aSymbol); xSeriesPropertySet->setPropertyValue( u"Symbol"_ustr, uno::Any( aSymbol ) ); } } beans::PropertyState WrappedSymbolSizeProperty::getPropertyState( const Reference< beans::XPropertyState >& xInnerPropertyState ) const { //only export symbol size if necessary if( m_ePropertyType == DIAGRAM ) return beans::PropertyState_DEFAULT_VALUE; try { chart2::Symbol aSymbol; Reference< beans::XPropertySet > xSeriesPropertySet( xInnerPropertyState, uno::UNO_QUERY ); if( xSeriesPropertySet.is() && ( xSeriesPropertySet->getPropertyValue(u"Symbol"_ustr) >>= aSymbol )) { if( aSymbol.Style != chart2::SymbolStyle_NONE ) return beans::PropertyState_DIRECT_VALUE; } } catch( const uno::Exception & ) { DBG_UNHANDLED_EXCEPTION("chart2"); } return beans::PropertyState_DEFAULT_VALUE; } WrappedSymbolAndLinesProperty::WrappedSymbolAndLinesProperty( const std::shared_ptr& spChart2ModelContact, tSeriesOrDiagramPropertyType ePropertyType ) : WrappedSeriesOrDiagramProperty< bool >( u"Lines"_ustr , uno::Any( true ), spChart2ModelContact, ePropertyType ) { } bool WrappedSymbolAndLinesProperty::getValueFromSeries( const Reference< beans::XPropertySet >& /*xSeriesPropertySet*/ ) const { //do not export this property anymore, instead use a linestyle none for no lines return true; } void WrappedSymbolAndLinesProperty::setValueToSeries( const Reference< beans::XPropertySet >& xSeriesPropertySet, const bool& bDrawLines ) const { if(!xSeriesPropertySet.is()) return; drawing::LineStyle eOldLineStyle( drawing::LineStyle_SOLID ); xSeriesPropertySet->getPropertyValue( u"LineStyle"_ustr ) >>= eOldLineStyle; if( bDrawLines ) { //#i114298# don't overwrite dashed lines with solid lines here if( eOldLineStyle == drawing::LineStyle_NONE ) xSeriesPropertySet->setPropertyValue( u"LineStyle"_ustr, uno::Any( drawing::LineStyle_SOLID ) ); } else { if( eOldLineStyle != drawing::LineStyle_NONE ) xSeriesPropertySet->setPropertyValue( u"LineStyle"_ustr, uno::Any( drawing::LineStyle_NONE ) ); } } beans::PropertyState WrappedSymbolAndLinesProperty::getPropertyState( const Reference< beans::XPropertyState >& /*xInnerPropertyState*/ ) const { //do not export this property anymore, instead use a linestyle none for no lines return beans::PropertyState_DEFAULT_VALUE; } } //namespace chart /* vim:set shiftwidth=4 softtabstop=4 expandtab: */