diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /chart2/source/controller/itemsetwrapper | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
16 files changed, 7139 insertions, 0 deletions
diff --git a/chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx b/chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx new file mode 100644 index 000000000..20ad1504f --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx @@ -0,0 +1,987 @@ +/* -*- 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 <AxisItemConverter.hxx> +#include <ItemPropertyMap.hxx> +#include <CharacterPropertyItemConverter.hxx> +#include <GraphicPropertyItemConverter.hxx> +#include <chartview/ChartSfxItemIds.hxx> +#include <chartview/ExplicitScaleValues.hxx> +#include <chartview/ExplicitValueProvider.hxx> +#include "SchWhichPairs.hxx" +#include <ChartModelHelper.hxx> +#include <ChartModel.hxx> +#include <Axis.hxx> +#include <AxisHelper.hxx> +#include <CommonConverters.hxx> +#include <ChartType.hxx> +#include <ChartTypeHelper.hxx> +#include <Diagram.hxx> +#include <unonames.hxx> +#include <BaseCoordinateSystem.hxx> +#include <memory> + +#include <com/sun/star/chart/ChartAxisLabelPosition.hpp> +#include <com/sun/star/chart/ChartAxisMarkPosition.hpp> +#include <com/sun/star/chart/ChartAxisPosition.hpp> +#include <com/sun/star/chart/TimeInterval.hpp> +#include <com/sun/star/chart2/XAxis.hpp> +#include <com/sun/star/chart2/AxisOrientation.hpp> +#include <com/sun/star/chart2/AxisType.hpp> + +#include <osl/diagnose.h> +#include <o3tl/any.hxx> +#include <svl/eitem.hxx> +#include <svx/chrtitem.hxx> +#include <svx/sdangitm.hxx> +#include <svl/intitem.hxx> +#include <rtl/math.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::chart::TimeInterval; +using ::com::sun::star::chart::TimeIncrement; + +namespace chart::wrapper { + +namespace { + +ItemPropertyMapType & lcl_GetAxisPropertyMap() +{ + static ItemPropertyMapType aAxisPropertyMap{ + {SCHATTR_AXIS_SHOWDESCR, {"DisplayLabels", 0}}, + {SCHATTR_AXIS_TICKS, {"MajorTickmarks", 0}}, + {SCHATTR_AXIS_HELPTICKS, {"MinorTickmarks", 0}}, + {SCHATTR_AXIS_LABEL_ORDER, {"ArrangeOrder", 0}}, + {SCHATTR_TEXT_STACKED, {"StackCharacters", 0}}, + {SCHATTR_AXIS_LABEL_BREAK, {"TextBreak", 0}}, + {SCHATTR_AXIS_LABEL_OVERLAP, {"TextOverlap", 0}}}; + return aAxisPropertyMap; +}; + +} // anonymous namespace + +AxisItemConverter::AxisItemConverter( + const Reference< beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const rtl::Reference<::chart::ChartModel> & xChartDoc, + ::chart::ExplicitScaleData const * pScale /* = NULL */, + ::chart::ExplicitIncrementData const * pIncrement /* = NULL */, + const awt::Size* pRefSize ) : + ItemConverter( rPropertySet, rItemPool ), + m_xChartDoc( xChartDoc ) +{ + if( pScale ) + m_pExplicitScale.reset( new ::chart::ExplicitScaleData( *pScale ) ); + if( pIncrement ) + m_pExplicitIncrement.reset( new ::chart::ExplicitIncrementData( *pIncrement ) ); + + m_aConverters.emplace_back( new GraphicPropertyItemConverter( + rPropertySet, rItemPool, rDrawModel, + xChartDoc, + GraphicObjectType::LineProperties )); + m_aConverters.emplace_back( + new CharacterPropertyItemConverter(rPropertySet, rItemPool, pRefSize, "ReferencePageSize")); + + m_xAxis.set( Reference< chart2::XAxis >( rPropertySet, uno::UNO_QUERY ) ); + OSL_ASSERT( m_xAxis.is()); +} + +AxisItemConverter::~AxisItemConverter() +{ +} + +void AxisItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + for( const auto& pConv : m_aConverters ) + pConv->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet( rOutItemSet ); +} + +bool AxisItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = false; + + for( const auto& pConv : m_aConverters ) + bResult = pConv->ApplyItemSet( rItemSet ) || bResult; + + // own items + return ItemConverter::ApplyItemSet( rItemSet ) || bResult; +} + +const WhichRangesContainer& AxisItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nAxisWhichPairs; +} + +bool AxisItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const +{ + ItemPropertyMapType & rMap( lcl_GetAxisPropertyMap()); + ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId )); + + if( aIt == rMap.end()) + return false; + + rOutProperty =(*aIt).second; + + return true; +} + +static bool lcl_hasTimeIntervalValue( const uno::Any& rAny ) +{ + bool bRet = false; + TimeInterval aValue; + if( rAny >>= aValue ) + bRet = true; + return bRet; +} + +void AxisItemConverter::FillSpecialItem( sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + if( !m_xAxis.is() ) + return; + + const chart2::ScaleData& rScale( m_xAxis->getScaleData() ); + const chart2::IncrementData& rIncrement( rScale.IncrementData ); + const uno::Sequence< chart2::SubIncrement >& rSubIncrements( rScale.IncrementData.SubIncrements ); + const TimeIncrement& rTimeIncrement( rScale.TimeIncrement ); + bool bDateAxis = (rScale.AxisType == chart2::AxisType::DATE); + if( m_pExplicitScale ) + bDateAxis = (m_pExplicitScale->AxisType == chart2::AxisType::DATE); + + switch( nWhichId ) + { + case SCHATTR_AXIS_AUTO_MAX: + rOutItemSet.Put( SfxBoolItem( nWhichId, !hasDoubleValue(rScale.Maximum) ) ); + break; + + case SCHATTR_AXIS_MAX: + { + double fMax = 10.0; + if( rScale.Maximum >>= fMax ) + rOutItemSet.Put( SvxDoubleItem( fMax, SCHATTR_AXIS_MAX ) ); + else + { + if( m_pExplicitScale ) + fMax = m_pExplicitScale->Maximum; + rOutItemSet.Put( SvxDoubleItem( fMax, SCHATTR_AXIS_MAX ) ); + } + } + break; + + case SCHATTR_AXIS_AUTO_MIN: + rOutItemSet.Put( SfxBoolItem( nWhichId, !hasDoubleValue(rScale.Minimum) ) ); + break; + + case SCHATTR_AXIS_MIN: + { + double fMin = 0.0; + if( rScale.Minimum >>= fMin ) + rOutItemSet.Put( SvxDoubleItem( fMin, SCHATTR_AXIS_MIN ) ); + else if( m_pExplicitScale ) + rOutItemSet.Put( SvxDoubleItem( m_pExplicitScale->Minimum, SCHATTR_AXIS_MIN )); + } + break; + + case SCHATTR_AXIS_LOGARITHM: + { + bool bValue = AxisHelper::isLogarithmic( rScale.Scaling ); + rOutItemSet.Put( SfxBoolItem( nWhichId, bValue )); + } + break; + + case SCHATTR_AXIS_REVERSE: + rOutItemSet.Put( SfxBoolItem( nWhichId, (rScale.Orientation == AxisOrientation_REVERSE) )); + break; + + // Increment + case SCHATTR_AXIS_AUTO_STEP_MAIN: + if( bDateAxis ) + rOutItemSet.Put( SfxBoolItem( nWhichId, !lcl_hasTimeIntervalValue(rTimeIncrement.MajorTimeInterval) ) ); + else + rOutItemSet.Put( SfxBoolItem( nWhichId, !hasDoubleValue(rIncrement.Distance) ) ); + break; + + case SCHATTR_AXIS_MAIN_TIME_UNIT: + { + TimeInterval aTimeInterval; + if( rTimeIncrement.MajorTimeInterval >>= aTimeInterval ) + rOutItemSet.Put( SfxInt32Item( nWhichId, aTimeInterval.TimeUnit ) ); + else if( m_pExplicitIncrement ) + rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitIncrement->MajorTimeInterval.TimeUnit ) ); + } + break; + + case SCHATTR_AXIS_STEP_MAIN: + if( bDateAxis ) + { + TimeInterval aTimeInterval; + if( rTimeIncrement.MajorTimeInterval >>= aTimeInterval ) + rOutItemSet.Put( SvxDoubleItem(aTimeInterval.Number, SCHATTR_AXIS_STEP_MAIN )); + else if( m_pExplicitIncrement ) + rOutItemSet.Put( SvxDoubleItem( m_pExplicitIncrement->MajorTimeInterval.Number, SCHATTR_AXIS_STEP_MAIN )); + } + else + { + double fDistance = 1.0; + if( rIncrement.Distance >>= fDistance ) + rOutItemSet.Put( SvxDoubleItem(fDistance, SCHATTR_AXIS_STEP_MAIN )); + else if( m_pExplicitIncrement ) + rOutItemSet.Put( SvxDoubleItem( m_pExplicitIncrement->Distance, SCHATTR_AXIS_STEP_MAIN )); + } + break; + + // SubIncrement + case SCHATTR_AXIS_AUTO_STEP_HELP: + if( bDateAxis ) + rOutItemSet.Put( SfxBoolItem( nWhichId, !lcl_hasTimeIntervalValue(rTimeIncrement.MinorTimeInterval) ) ); + else + rOutItemSet.Put( SfxBoolItem( nWhichId, + ! ( rSubIncrements.hasElements() && rSubIncrements[0].IntervalCount.hasValue() ))); + break; + + case SCHATTR_AXIS_HELP_TIME_UNIT: + { + TimeInterval aTimeInterval; + if( rTimeIncrement.MinorTimeInterval >>= aTimeInterval ) + rOutItemSet.Put( SfxInt32Item( nWhichId, aTimeInterval.TimeUnit ) ); + else if( m_pExplicitIncrement ) + rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitIncrement->MinorTimeInterval.TimeUnit ) ); + } + break; + + case SCHATTR_AXIS_STEP_HELP: + if( bDateAxis ) + { + TimeInterval aTimeInterval; + if( rTimeIncrement.MinorTimeInterval >>= aTimeInterval ) + rOutItemSet.Put( SfxInt32Item( nWhichId, aTimeInterval.Number )); + else if( m_pExplicitIncrement ) + rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitIncrement->MinorTimeInterval.Number )); + } + else + { + if( rSubIncrements.hasElements() && rSubIncrements[0].IntervalCount.hasValue()) + { + rOutItemSet.Put( SfxInt32Item( nWhichId, + *o3tl::doAccess<sal_Int32>( + rSubIncrements[0].IntervalCount) )); + } + else + { + if( m_pExplicitIncrement && !m_pExplicitIncrement->SubIncrements.empty() ) + { + rOutItemSet.Put( SfxInt32Item( nWhichId, + m_pExplicitIncrement->SubIncrements[0].IntervalCount )); + } + } + } + break; + + case SCHATTR_AXIS_AUTO_TIME_RESOLUTION: + { + rOutItemSet.Put( SfxBoolItem( nWhichId, + !rTimeIncrement.TimeResolution.hasValue() )); + } + break; + case SCHATTR_AXIS_TIME_RESOLUTION: + { + sal_Int32 nTimeResolution=0; + if( rTimeIncrement.TimeResolution >>= nTimeResolution ) + rOutItemSet.Put( SfxInt32Item( nWhichId, nTimeResolution ) ); + else if( m_pExplicitScale ) + rOutItemSet.Put( SfxInt32Item( nWhichId, m_pExplicitScale->TimeResolution ) ); + } + break; + + case SCHATTR_AXIS_AUTO_ORIGIN: + { + rOutItemSet.Put( SfxBoolItem( nWhichId, ( !hasDoubleValue(rScale.Origin) ))); + } + break; + + case SCHATTR_AXIS_ORIGIN: + { + double fOrigin = 0.0; + if( !(rScale.Origin >>= fOrigin) ) + { + if( m_pExplicitScale ) + fOrigin = m_pExplicitScale->Origin; + } + rOutItemSet.Put( SvxDoubleItem( fOrigin, SCHATTR_AXIS_ORIGIN )); + } + break; + + case SCHATTR_AXIS_POSITION: + { + css::chart::ChartAxisPosition eAxisPos( css::chart::ChartAxisPosition_ZERO ); + GetPropertySet()->getPropertyValue( "CrossoverPosition" ) >>= eAxisPos; + rOutItemSet.Put( SfxInt32Item( nWhichId, static_cast<sal_Int32>(eAxisPos) ) ); + } + break; + + case SCHATTR_AXIS_POSITION_VALUE: + { + double fValue = 0.0; + if( GetPropertySet()->getPropertyValue( "CrossoverValue" ) >>= fValue ) + rOutItemSet.Put( SvxDoubleItem( fValue, SCHATTR_AXIS_POSITION_VALUE ) ); + } + break; + + case SCHATTR_AXIS_CROSSING_MAIN_AXIS_NUMBERFORMAT: + { + //read only item + //necessary tp display the crossing value with an appropriate format + + rtl::Reference< BaseCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( + m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) ); + + rtl::Reference< Axis > xCrossingMainAxis = AxisHelper::getCrossingMainAxis( m_xAxis, xCooSys ); + + sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( + xCrossingMainAxis, xCooSys, m_xChartDoc); + + rOutItemSet.Put( SfxUInt32Item( nWhichId, nFormatKey )); + } + break; + + case SCHATTR_AXIS_SHIFTED_CATEGORY_POSITION: + rOutItemSet.Put(SfxBoolItem(nWhichId, rScale.ShiftedCategoryPosition)); + break; + + case SCHATTR_AXIS_LABEL_POSITION: + { + css::chart::ChartAxisLabelPosition ePos( css::chart::ChartAxisLabelPosition_NEAR_AXIS ); + GetPropertySet()->getPropertyValue( "LabelPosition" ) >>= ePos; + rOutItemSet.Put( SfxInt32Item( nWhichId, static_cast<sal_Int32>(ePos) ) ); + } + break; + + case SCHATTR_AXIS_MARK_POSITION: + { + css::chart::ChartAxisMarkPosition ePos( css::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS ); + GetPropertySet()->getPropertyValue( "MarkPosition" ) >>= ePos; + rOutItemSet.Put( SfxInt32Item( nWhichId, static_cast<sal_Int32>(ePos) ) ); + } + break; + + case SCHATTR_TEXT_DEGREES: + { + // convert double to int (times 100) + double fVal = 0; + + if( GetPropertySet()->getPropertyValue( "TextRotation" ) >>= fVal ) + { + rOutItemSet.Put( SdrAngleItem( SCHATTR_TEXT_DEGREES, Degree100(static_cast< sal_Int32 >( + ::rtl::math::round( fVal * 100.0 )) ) )); + } + } + break; + + case SID_ATTR_NUMBERFORMAT_VALUE: + { + if( m_pExplicitScale ) + { + rtl::Reference< BaseCoordinateSystem > xCooSys( + AxisHelper::getCoordinateSystemOfAxis( + m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) ); + + sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( + m_xAxis, xCooSys, m_xChartDoc); + + rOutItemSet.Put( SfxUInt32Item( nWhichId, nFormatKey )); + } + } + break; + + case SID_ATTR_NUMBERFORMAT_SOURCE: + { + bool bLinkToSource = true; + GetPropertySet()->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT) >>= bLinkToSource; + rOutItemSet.Put(SfxBoolItem(nWhichId, bLinkToSource)); + } + break; + + case SCHATTR_AXISTYPE: + rOutItemSet.Put( SfxInt32Item( nWhichId, rScale.AxisType )); + break; + + case SCHATTR_AXIS_AUTO_DATEAXIS: + rOutItemSet.Put( SfxBoolItem( nWhichId, rScale.AutoDateAxis )); + break; + + case SCHATTR_AXIS_ALLOW_DATEAXIS: + { + rtl::Reference< BaseCoordinateSystem > xCooSys( + AxisHelper::getCoordinateSystemOfAxis( m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) ); + sal_Int32 nDimensionIndex=0; sal_Int32 nAxisIndex=0; + AxisHelper::getIndicesForAxis(m_xAxis, xCooSys, nDimensionIndex, nAxisIndex ); + bool bChartTypeAllowsDateAxis = ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys, 0 ), nDimensionIndex ); + rOutItemSet.Put( SfxBoolItem( nWhichId, bChartTypeAllowsDateAxis )); + } + break; + } +} + +static bool lcl_isDateAxis( const SfxItemSet & rItemSet ) +{ + sal_Int32 nAxisType = rItemSet.Get( SCHATTR_AXISTYPE ).GetValue();//css::chart2::AxisType + return (nAxisType == chart2::AxisType::DATE); +} + +static bool lcl_isAutoMajor( const SfxItemSet & rItemSet ) +{ + bool bRet = rItemSet.Get( SCHATTR_AXIS_AUTO_STEP_MAIN ).GetValue(); + return bRet; +} + +static bool lcl_isAutoMinor( const SfxItemSet & rItemSet ) +{ + bool bRet = rItemSet.Get( SCHATTR_AXIS_AUTO_STEP_HELP ).GetValue(); + return bRet; +} + +bool AxisItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + if( !m_xAxis.is() ) + return false; + + chart2::ScaleData aScale( m_xAxis->getScaleData() ); + + bool bSetScale = false; + bool bChangedOtherwise = false; + + uno::Any aValue; + + switch( nWhichId ) + { + case SCHATTR_AXIS_AUTO_MAX: + if( static_cast< const SfxBoolItem & >(rItemSet.Get( nWhichId )).GetValue() ) + { + aScale.Maximum.clear(); + bSetScale = true; + } + // else SCHATTR_AXIS_MAX must have some value + break; + + case SCHATTR_AXIS_MAX: + // only if auto if false + if( ! (rItemSet.Get( SCHATTR_AXIS_AUTO_MAX ).GetValue() )) + { + rItemSet.Get( nWhichId ).QueryValue( aValue ); + + if( aScale.Maximum != aValue ) + { + aScale.Maximum = aValue; + bSetScale = true; + } + } + break; + + case SCHATTR_AXIS_AUTO_MIN: + if( static_cast< const SfxBoolItem & >(rItemSet.Get( nWhichId )).GetValue() ) + { + aScale.Minimum.clear(); + bSetScale = true; + } + // else SCHATTR_AXIS_MIN must have some value + break; + + case SCHATTR_AXIS_MIN: + // only if auto if false + if( ! (rItemSet.Get( SCHATTR_AXIS_AUTO_MIN ).GetValue() )) + { + rItemSet.Get( nWhichId ).QueryValue( aValue ); + + if( aScale.Minimum != aValue ) + { + aScale.Minimum = aValue; + bSetScale = true; + } + } + break; + + case SCHATTR_AXIS_LOGARITHM: + { + bool bWasLogarithm = AxisHelper::isLogarithmic( aScale.Scaling ); + + if( static_cast< const SfxBoolItem & >(rItemSet.Get( nWhichId )).GetValue() ) + { + // logarithm is true + if( ! bWasLogarithm ) + { + aScale.Scaling = AxisHelper::createLogarithmicScaling( 10.0 ); + bSetScale = true; + } + } + else + { + // logarithm is false => linear scaling + if( bWasLogarithm ) + { + aScale.Scaling = AxisHelper::createLinearScaling(); + bSetScale = true; + } + } + } + break; + + case SCHATTR_AXIS_REVERSE: + { + bool bWasReverse = ( aScale.Orientation == AxisOrientation_REVERSE ); + bool bNewReverse = static_cast< const SfxBoolItem & >( + rItemSet.Get( nWhichId )).GetValue(); + if( bWasReverse != bNewReverse ) + { + aScale.Orientation = bNewReverse ? AxisOrientation_REVERSE : AxisOrientation_MATHEMATICAL; + bSetScale = true; + } + } + break; + + // Increment + case SCHATTR_AXIS_AUTO_STEP_MAIN: + if( lcl_isAutoMajor(rItemSet) ) + { + aScale.IncrementData.Distance.clear(); + aScale.TimeIncrement.MajorTimeInterval.clear(); + bSetScale = true; + } + // else SCHATTR_AXIS_STEP_MAIN must have some value + break; + + case SCHATTR_AXIS_MAIN_TIME_UNIT: + if( !lcl_isAutoMajor(rItemSet) ) + { + if( rItemSet.Get( nWhichId ).QueryValue( aValue ) ) + { + TimeInterval aTimeInterval; + aScale.TimeIncrement.MajorTimeInterval >>= aTimeInterval; + aValue >>= aTimeInterval.TimeUnit; + aScale.TimeIncrement.MajorTimeInterval <<= aTimeInterval; + bSetScale = true; + } + } + break; + + case SCHATTR_AXIS_STEP_MAIN: + // only if auto if false + if( !lcl_isAutoMajor(rItemSet) ) + { + rItemSet.Get( nWhichId ).QueryValue( aValue ); + if( lcl_isDateAxis(rItemSet) ) + { + double fValue = 1.0; + if( aValue >>= fValue ) + { + TimeInterval aTimeInterval; + aScale.TimeIncrement.MajorTimeInterval >>= aTimeInterval; + aTimeInterval.Number = static_cast<sal_Int32>(fValue); + aScale.TimeIncrement.MajorTimeInterval <<= aTimeInterval; + bSetScale = true; + } + } + else if( aScale.IncrementData.Distance != aValue ) + { + aScale.IncrementData.Distance = aValue; + bSetScale = true; + } + } + break; + + // SubIncrement + case SCHATTR_AXIS_AUTO_STEP_HELP: + if( lcl_isAutoMinor(rItemSet) ) + { + if( aScale.IncrementData.SubIncrements.hasElements() && + aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() ) + { + aScale.IncrementData.SubIncrements.getArray()[0].IntervalCount.clear(); + bSetScale = true; + } + if( aScale.TimeIncrement.MinorTimeInterval.hasValue() ) + { + aScale.TimeIncrement.MinorTimeInterval.clear(); + bSetScale = true; + } + } + // else SCHATTR_AXIS_STEP_MAIN must have some value + break; + + case SCHATTR_AXIS_HELP_TIME_UNIT: + if( !lcl_isAutoMinor(rItemSet) ) + { + if( rItemSet.Get( nWhichId ).QueryValue( aValue ) ) + { + TimeInterval aTimeInterval; + aScale.TimeIncrement.MinorTimeInterval >>= aTimeInterval; + aValue >>= aTimeInterval.TimeUnit; + aScale.TimeIncrement.MinorTimeInterval <<= aTimeInterval; + bSetScale = true; + } + } + break; + + case SCHATTR_AXIS_STEP_HELP: + // only if auto is false + if( !lcl_isAutoMinor(rItemSet) ) + { + rItemSet.Get( nWhichId ).QueryValue( aValue ); + if( lcl_isDateAxis(rItemSet) ) + { + TimeInterval aTimeInterval; + aScale.TimeIncrement.MinorTimeInterval >>= aTimeInterval; + aValue >>= aTimeInterval.Number; + aScale.TimeIncrement.MinorTimeInterval <<= aTimeInterval; + bSetScale = true; + } + else if( aScale.IncrementData.SubIncrements.hasElements() ) + { + if( ! aScale.IncrementData.SubIncrements[0].IntervalCount.hasValue() || + aScale.IncrementData.SubIncrements[0].IntervalCount != aValue ) + { + OSL_ASSERT( aValue.getValueTypeClass() == uno::TypeClass_LONG ); + aScale.IncrementData.SubIncrements.getArray()[0].IntervalCount = aValue; + bSetScale = true; + } + } + } + break; + + case SCHATTR_AXIS_AUTO_TIME_RESOLUTION: + if( static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue() ) + { + aScale.TimeIncrement.TimeResolution.clear(); + bSetScale = true; + } + break; + case SCHATTR_AXIS_TIME_RESOLUTION: + // only if auto is false + if( ! ( rItemSet.Get( SCHATTR_AXIS_AUTO_TIME_RESOLUTION ).GetValue() )) + { + rItemSet.Get( nWhichId ).QueryValue( aValue ); + + if( aScale.TimeIncrement.TimeResolution != aValue ) + { + aScale.TimeIncrement.TimeResolution = aValue; + bSetScale = true; + } + } + break; + + case SCHATTR_AXIS_AUTO_ORIGIN: + { + if( static_cast< const SfxBoolItem & >(rItemSet.Get( nWhichId )).GetValue() ) + { + aScale.Origin.clear(); + bSetScale = true; + } + } + break; + + case SCHATTR_AXIS_ORIGIN: + { + // only if auto is false + if( ! (rItemSet.Get( SCHATTR_AXIS_AUTO_ORIGIN ).GetValue() )) + { + rItemSet.Get( nWhichId ).QueryValue( aValue ); + + if( aScale.Origin != aValue ) + { + aScale.Origin = aValue; + bSetScale = true; + + if( !AxisHelper::isAxisPositioningEnabled() ) + { + //keep old and new settings for axis positioning in sync somehow + rtl::Reference< BaseCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( + m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) ); + + sal_Int32 nDimensionIndex=0; + sal_Int32 nAxisIndex=0; + if( AxisHelper::getIndicesForAxis( m_xAxis, xCooSys, nDimensionIndex, nAxisIndex ) && nAxisIndex==0 ) + { + rtl::Reference< Axis > xCrossingMainAxis = AxisHelper::getCrossingMainAxis( m_xAxis, xCooSys ); + if( xCrossingMainAxis.is() ) + { + double fValue = 0.0; + if( aValue >>= fValue ) + { + xCrossingMainAxis->setPropertyValue( "CrossoverPosition" , uno::Any( css::chart::ChartAxisPosition_VALUE )); + xCrossingMainAxis->setPropertyValue( "CrossoverValue" , uno::Any( fValue )); + } + else + xCrossingMainAxis->setPropertyValue( "CrossoverPosition" , uno::Any( css::chart::ChartAxisPosition_START )); + } + } + } + } + } + } + break; + + case SCHATTR_AXIS_POSITION: + { + css::chart::ChartAxisPosition eAxisPos = + static_cast<css::chart::ChartAxisPosition>(static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue()); + + css::chart::ChartAxisPosition eOldAxisPos( css::chart::ChartAxisPosition_ZERO ); + bool bPropExisted = ( GetPropertySet()->getPropertyValue( "CrossoverPosition" ) >>= eOldAxisPos ); + + if( !bPropExisted || ( eOldAxisPos != eAxisPos )) + { + GetPropertySet()->setPropertyValue( "CrossoverPosition" , uno::Any( eAxisPos )); + bChangedOtherwise = true; + + //move the parallel axes to the other side if necessary + if( eAxisPos==css::chart::ChartAxisPosition_START || eAxisPos==css::chart::ChartAxisPosition_END ) + { + rtl::Reference< Axis > xParallelAxis = AxisHelper::getParallelAxis( m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ); + if( xParallelAxis.is() ) + { + css::chart::ChartAxisPosition eOtherPos; + if( xParallelAxis->getPropertyValue( "CrossoverPosition" ) >>= eOtherPos ) + { + if( eOtherPos == eAxisPos ) + { + css::chart::ChartAxisPosition eOppositePos = + (eAxisPos==css::chart::ChartAxisPosition_START) + ? css::chart::ChartAxisPosition_END + : css::chart::ChartAxisPosition_START; + xParallelAxis->setPropertyValue( "CrossoverPosition" , uno::Any( eOppositePos )); + } + } + } + } + } + } + break; + + case SCHATTR_AXIS_POSITION_VALUE: + { + double fValue = static_cast< const SvxDoubleItem & >( rItemSet.Get( nWhichId )).GetValue(); + + double fOldValue = 0.0; + bool bPropExisted = ( GetPropertySet()->getPropertyValue( "CrossoverValue" ) >>= fOldValue ); + + if( !bPropExisted || ( fOldValue != fValue )) + { + GetPropertySet()->setPropertyValue( "CrossoverValue" , uno::Any( fValue )); + bChangedOtherwise = true; + + //keep old and new settings for axis positioning in sync somehow + { + rtl::Reference< BaseCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( + m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) ); + + sal_Int32 nDimensionIndex=0; + sal_Int32 nAxisIndex=0; + if( AxisHelper::getIndicesForAxis( m_xAxis, xCooSys, nDimensionIndex, nAxisIndex ) && nAxisIndex==0 ) + { + Reference< chart2::XAxis > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( m_xAxis, xCooSys ) ); + if( xCrossingMainAxis.is() ) + { + ScaleData aCrossingScale( xCrossingMainAxis->getScaleData() ); + aCrossingScale.Origin <<= fValue; + xCrossingMainAxis->setScaleData(aCrossingScale); + } + } + } + } + } + break; + + case SCHATTR_AXIS_SHIFTED_CATEGORY_POSITION: + { + bool bNewValue = static_cast<const SfxBoolItem &> (rItemSet.Get(nWhichId)).GetValue(); + bool bOldValue = aScale.ShiftedCategoryPosition; + if (bOldValue != bNewValue) + { + aScale.ShiftedCategoryPosition = bNewValue; + bSetScale = true; + } + } + break; + + case SCHATTR_AXIS_LABEL_POSITION: + { + css::chart::ChartAxisLabelPosition ePos = + static_cast<css::chart::ChartAxisLabelPosition>(static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue()); + + css::chart::ChartAxisLabelPosition eOldPos( css::chart::ChartAxisLabelPosition_NEAR_AXIS ); + bool bPropExisted = ( GetPropertySet()->getPropertyValue( "LabelPosition" ) >>= eOldPos ); + + if( !bPropExisted || ( eOldPos != ePos )) + { + GetPropertySet()->setPropertyValue( "LabelPosition" , uno::Any( ePos )); + bChangedOtherwise = true; + + //move the parallel axes to the other side if necessary + if( ePos==css::chart::ChartAxisLabelPosition_OUTSIDE_START || ePos==css::chart::ChartAxisLabelPosition_OUTSIDE_END ) + { + rtl::Reference< Axis > xParallelAxis = AxisHelper::getParallelAxis( m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ); + if( xParallelAxis.is() ) + { + css::chart::ChartAxisLabelPosition eOtherPos; + if( xParallelAxis->getPropertyValue( "LabelPosition" ) >>= eOtherPos ) + { + if( eOtherPos == ePos ) + { + css::chart::ChartAxisLabelPosition eOppositePos = + (ePos==css::chart::ChartAxisLabelPosition_OUTSIDE_START) + ? css::chart::ChartAxisLabelPosition_OUTSIDE_END + : css::chart::ChartAxisLabelPosition_OUTSIDE_START; + xParallelAxis->setPropertyValue( "LabelPosition" , uno::Any( eOppositePos )); + } + } + } + } + } + } + break; + + case SCHATTR_AXIS_MARK_POSITION: + { + css::chart::ChartAxisMarkPosition ePos = + static_cast<css::chart::ChartAxisMarkPosition>(static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue()); + + css::chart::ChartAxisMarkPosition eOldPos( css::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS ); + bool bPropExisted = ( GetPropertySet()->getPropertyValue( "MarkPosition" ) >>= eOldPos ); + + if( !bPropExisted || ( eOldPos != ePos )) + { + GetPropertySet()->setPropertyValue( "MarkPosition" , uno::Any( ePos )); + bChangedOtherwise = true; + } + } + break; + + case SCHATTR_TEXT_DEGREES: + { + double fVal = toDegrees(rItemSet.Get(SCHATTR_TEXT_DEGREES).GetValue()); + double fOldVal = 0.0; + bool bPropExisted = + ( GetPropertySet()->getPropertyValue( "TextRotation" ) >>= fOldVal ); + + if( ! bPropExisted || fOldVal != fVal ) + { + GetPropertySet()->setPropertyValue( "TextRotation" , uno::Any( fVal )); + bChangedOtherwise = true; + } + } + break; + + case SID_ATTR_NUMBERFORMAT_VALUE: + { + if( m_pExplicitScale ) + { + bool bUseSourceFormat = + rItemSet.Get( SID_ATTR_NUMBERFORMAT_SOURCE ).GetValue(); + + if( ! bUseSourceFormat ) + { + sal_Int32 nFmt = static_cast< sal_Int32 >( + static_cast< const SfxUInt32Item & >( + rItemSet.Get( nWhichId )).GetValue()); + + aValue <<= nFmt; + if (GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT) != aValue) + { + GetPropertySet()->setPropertyValue(CHART_UNONAME_NUMFMT , aValue); + bChangedOtherwise = true; + } + } + } + } + break; + + case SID_ATTR_NUMBERFORMAT_SOURCE: + { + bool bUseSourceFormat = + static_cast< const SfxBoolItem & >( + rItemSet.Get( nWhichId )).GetValue(); + GetPropertySet()->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::Any(bUseSourceFormat)); + + bool bNumberFormatIsSet = GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT).hasValue(); + + bChangedOtherwise = (bUseSourceFormat == bNumberFormatIsSet); + if( bChangedOtherwise ) + { + if( ! bUseSourceFormat ) + { + SfxItemState aState = rItemSet.GetItemState( SID_ATTR_NUMBERFORMAT_VALUE ); + if( aState == SfxItemState::SET ) + { + sal_Int32 nFormatKey = static_cast< sal_Int32 >( + rItemSet.Get( SID_ATTR_NUMBERFORMAT_VALUE ).GetValue()); + aValue <<= nFormatKey; + } + else + { + rtl::Reference< BaseCoordinateSystem > xCooSys = + AxisHelper::getCoordinateSystemOfAxis( + m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ); + + sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( + m_xAxis, xCooSys, m_xChartDoc); + + aValue <<= nFormatKey; + } + } + // else set a void Any + GetPropertySet()->setPropertyValue(CHART_UNONAME_NUMFMT , aValue); + } + } + break; + + case SCHATTR_AXISTYPE: + { + sal_Int32 nNewAxisType = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue();//css::chart2::AxisType + aScale.AxisType = nNewAxisType; + bSetScale = true; + } + break; + + case SCHATTR_AXIS_AUTO_DATEAXIS: + { + bool bNewValue = static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue(); + bool bOldValue = aScale.AutoDateAxis; + if( bOldValue != bNewValue ) + { + aScale.AutoDateAxis = bNewValue; + bSetScale = true; + } + } + break; + } + + if( bSetScale ) + m_xAxis->setScaleData( aScale ); + + return (bSetScale || bChangedOtherwise); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/CharacterPropertyItemConverter.cxx b/chart2/source/controller/itemsetwrapper/CharacterPropertyItemConverter.cxx new file mode 100644 index 000000000..5345f9168 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/CharacterPropertyItemConverter.cxx @@ -0,0 +1,556 @@ +/* -*- 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 <CharacterPropertyItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <ItemPropertyMap.hxx> +#include <RelativeSizeHelper.hxx> +#include <editeng/memberids.h> +#include <editeng/eeitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <o3tl/any.hxx> +#include <svl/stritem.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/chart2/XFormattedString.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +namespace chart::wrapper { + +namespace { + +ItemPropertyMapType & lcl_GetCharacterPropertyPropertyMap() +{ + static ItemPropertyMapType aCharacterPropertyMap{ + {EE_CHAR_COLOR, {"CharColor", 0}}, + {EE_CHAR_LANGUAGE, {"CharLocale", MID_LANG_LOCALE}}, + {EE_CHAR_LANGUAGE_CJK, {"CharLocaleAsian", MID_LANG_LOCALE}}, + {EE_CHAR_LANGUAGE_CTL, {"CharLocaleComplex", MID_LANG_LOCALE}}, + + {EE_CHAR_STRIKEOUT, {"CharStrikeout", MID_CROSS_OUT}}, + {EE_CHAR_WLM, {"CharWordMode", 0}}, + {EE_CHAR_SHADOW, {"CharShadowed", 0}}, + {EE_CHAR_RELIEF, {"CharRelief", 0}}, + {EE_CHAR_OUTLINE, {"CharContoured", 0}}, + {EE_CHAR_EMPHASISMARK, {"CharEmphasis", 0}}, + + {EE_PARA_WRITINGDIR, {"WritingMode", 0}}, + + {EE_PARA_ASIANCJKSPACING, {"ParaIsCharacterDistance", 0}}}; + + return aCharacterPropertyMap; +} +} // anonymous namespace + +CharacterPropertyItemConverter::CharacterPropertyItemConverter( + const uno::Reference< beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool ) : + ItemConverter( rPropertySet, rItemPool ) +{} + +CharacterPropertyItemConverter::CharacterPropertyItemConverter( + const uno::Reference< beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool, + const awt::Size* pRefSize, + const OUString & rRefSizePropertyName, + const uno::Reference< beans::XPropertySet > & rRefSizePropSet ) : + ItemConverter( rPropertySet, rItemPool ), + m_aRefSizePropertyName( rRefSizePropertyName ), + m_xRefSizePropSet( rRefSizePropSet.is() ? rRefSizePropSet : rPropertySet ) +{ + if (pRefSize) + m_pRefSize = *pRefSize; +} + +CharacterPropertyItemConverter::~CharacterPropertyItemConverter() +{} + +const WhichRangesContainer& CharacterPropertyItemConverter::GetWhichPairs() const +{ + return nCharacterPropertyWhichPairs; +} + +bool CharacterPropertyItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const +{ + ItemPropertyMapType & rMap( lcl_GetCharacterPropertyPropertyMap()); + ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId )); + + if( aIt == rMap.end()) + return false; + + rOutProperty =(*aIt).second; + return true; +} + +void CharacterPropertyItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case EE_CHAR_FONTINFO: + case EE_CHAR_FONTINFO_CJK: + case EE_CHAR_FONTINFO_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_FONTINFO_CJK ) + aPostfix = "Asian"; + else if( nWhichId == EE_CHAR_FONTINFO_CTL ) + aPostfix = "Complex"; + + SvxFontItem aItem( nWhichId ); + + aItem.PutValue( GetPropertySet()->getPropertyValue( "CharFontName" + aPostfix), + MID_FONT_FAMILY_NAME ); + aItem.PutValue( GetPropertySet()->getPropertyValue( "CharFontFamily" + aPostfix), + MID_FONT_FAMILY ); + aItem.PutValue( GetPropertySet()->getPropertyValue( "CharFontStyleName" + aPostfix), + MID_FONT_STYLE_NAME ); + aItem.PutValue( GetPropertySet()->getPropertyValue( "CharFontCharSet" + aPostfix), + MID_FONT_CHAR_SET ); + aItem.PutValue( GetPropertySet()->getPropertyValue( "CharFontPitch" + aPostfix), + MID_FONT_PITCH ); + + rOutItemSet.Put( aItem ); + } + break; + + case EE_CHAR_UNDERLINE: + { + SvxUnderlineItem aItem(LINESTYLE_NONE, EE_CHAR_UNDERLINE); + bool bModified = false; + + uno::Any aValue( GetPropertySet()->getPropertyValue( "CharUnderline" )); + if( aValue.hasValue()) + { + aItem.PutValue( aValue, MID_TL_STYLE ); + bModified = true; + } + + aValue = GetPropertySet()->getPropertyValue( "CharUnderlineHasColor" ); + if( aValue.hasValue() && *o3tl::doAccess<bool>(aValue) ) + { + aItem.PutValue( aValue, MID_TL_HASCOLOR ); + bModified = true; + } + + aValue = GetPropertySet()->getPropertyValue( "CharUnderlineColor" ); + if( aValue.hasValue()) + { + aItem.PutValue( aValue, MID_TL_COLOR ); + bModified = true; + } + + if( bModified ) + rOutItemSet.Put( aItem ); + } + break; + + case EE_CHAR_OVERLINE: + { + SvxOverlineItem aItem( LINESTYLE_NONE, EE_CHAR_OVERLINE ); + bool bModified = false; + + uno::Any aValue( GetPropertySet()->getPropertyValue( "CharOverline" ) ); + if ( aValue.hasValue() ) + { + aItem.PutValue( aValue, MID_TL_STYLE ); + bModified = true; + } + + aValue = GetPropertySet()->getPropertyValue( "CharOverlineHasColor" ); + if ( aValue.hasValue() && *o3tl::doAccess<bool>(aValue) ) + { + aItem.PutValue( aValue, MID_TL_HASCOLOR ); + bModified = true; + } + + aValue = GetPropertySet()->getPropertyValue( "CharOverlineColor" ); + if ( aValue.hasValue() ) + { + aItem.PutValue( aValue, MID_TL_COLOR ); + bModified = true; + } + + if ( bModified ) + { + rOutItemSet.Put( aItem ); + } + } + break; + + case EE_CHAR_ITALIC: + case EE_CHAR_ITALIC_CJK: + case EE_CHAR_ITALIC_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_ITALIC_CJK ) + aPostfix = "Asian"; + else if( nWhichId == EE_CHAR_ITALIC_CTL ) + aPostfix = "Complex"; + + SvxPostureItem aItem( ITALIC_NONE, nWhichId ); + + uno::Any aValue( GetPropertySet()->getPropertyValue( "CharPosture" + aPostfix)); + if( aValue.hasValue()) + { + aItem.PutValue( aValue, MID_POSTURE ); + rOutItemSet.Put( aItem ); + } + } + break; + + case EE_CHAR_WEIGHT: + case EE_CHAR_WEIGHT_CJK: + case EE_CHAR_WEIGHT_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_WEIGHT_CJK ) + aPostfix = "Asian"; + else if( nWhichId == EE_CHAR_WEIGHT_CTL ) + aPostfix = "Complex"; + + SvxWeightItem aItem( WEIGHT_NORMAL, nWhichId ); + + uno::Any aValue( GetPropertySet()->getPropertyValue( "CharWeight" + aPostfix)); + if( aValue.hasValue()) + { + aItem.PutValue( aValue, MID_WEIGHT ); + rOutItemSet.Put( aItem ); + } + } + break; + + case EE_CHAR_FONTHEIGHT: + case EE_CHAR_FONTHEIGHT_CJK: + case EE_CHAR_FONTHEIGHT_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_FONTHEIGHT_CJK ) + aPostfix = "Asian"; + else if( nWhichId == EE_CHAR_FONTHEIGHT_CTL ) + aPostfix = "Complex"; + + SvxFontHeightItem aItem( 240, 100, nWhichId ); + + try + { + uno::Any aValue( GetPropertySet()->getPropertyValue( "CharHeight" + aPostfix )); + float fHeight; + if( aValue >>= fHeight ) + { + if (m_pRefSize) + { + awt::Size aOldRefSize; + if( GetRefSizePropertySet()->getPropertyValue( m_aRefSizePropertyName ) >>= aOldRefSize ) + { + // calculate font height in view + fHeight = static_cast< float >( + RelativeSizeHelper::calculate( fHeight, aOldRefSize, *m_pRefSize )); + aValue <<= fHeight; + } + } + + aItem.PutValue( aValue, MID_FONTHEIGHT ); + rOutItemSet.Put( aItem ); + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + break; + + case SID_CHAR_DLG_PREVIEW_STRING: + { + uno::Reference< chart2::XFormattedString > xFormattedString( GetPropertySet(), uno::UNO_QUERY ); + if( xFormattedString.is() ) + { + OUString aString = xFormattedString->getString(); + rOutItemSet.Put( SfxStringItem( nWhichId, aString ) ); + } + else + rOutItemSet.Put( SfxStringItem( nWhichId, OUString() ) ); + } + break; + + case EE_PARA_FORBIDDENRULES: + case EE_PARA_HANGINGPUNCTUATION: + rOutItemSet.DisableItem( nWhichId ); + break; + } +} + +bool CharacterPropertyItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + uno::Any aValue; + + switch( nWhichId ) + { + case EE_CHAR_FONTINFO: + case EE_CHAR_FONTINFO_CJK: + case EE_CHAR_FONTINFO_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_FONTINFO_CJK ) + aPostfix = "Asian"; + else if( nWhichId == EE_CHAR_FONTINFO_CTL ) + aPostfix = "Complex"; + + const SvxFontItem & rItem = + static_cast< const SvxFontItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_FONT_FAMILY_NAME )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharFontName" + aPostfix )) + { + GetPropertySet()->setPropertyValue( "CharFontName" + aPostfix, aValue ); + bChanged = true; + } + } + if( rItem.QueryValue( aValue, MID_FONT_FAMILY )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharFontFamily" + aPostfix )) + { + GetPropertySet()->setPropertyValue( "CharFontFamily" + aPostfix, aValue ); + bChanged = true; + } + } + if( rItem.QueryValue( aValue, MID_FONT_STYLE_NAME )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharFontStyleName" + aPostfix )) + { + GetPropertySet()->setPropertyValue( "CharFontStyleName" + aPostfix, aValue ); + bChanged = true; + } + } + if( rItem.QueryValue( aValue, MID_FONT_CHAR_SET )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharFontCharSet" + aPostfix )) + { + GetPropertySet()->setPropertyValue( "CharFontCharSet" + aPostfix, aValue ); + bChanged = true; + } + } + if( rItem.QueryValue( aValue, MID_FONT_PITCH )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharFontPitch" + aPostfix )) + { + GetPropertySet()->setPropertyValue( "CharFontPitch" + aPostfix, aValue ); + bChanged = true; + } + } + } + break; + + case EE_CHAR_UNDERLINE: + { + const SvxUnderlineItem & rItem = + static_cast< const SvxUnderlineItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_TL_STYLE )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharUnderline" )) + { + GetPropertySet()->setPropertyValue( "CharUnderline" , aValue ); + bChanged = true; + } + } + + if( rItem.QueryValue( aValue, MID_TL_COLOR )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharUnderlineColor" )) + { + GetPropertySet()->setPropertyValue( "CharUnderlineColor" , aValue ); + bChanged = true; + } + } + + if( rItem.QueryValue( aValue, MID_TL_HASCOLOR )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharUnderlineHasColor" )) + { + GetPropertySet()->setPropertyValue( "CharUnderlineHasColor" , aValue ); + bChanged = true; + } + } + } + break; + + case EE_CHAR_OVERLINE: + { + const SvxOverlineItem& rItem = static_cast< const SvxOverlineItem & >( rItemSet.Get( nWhichId ) ); + + if ( rItem.QueryValue( aValue, MID_TL_STYLE ) ) + { + if ( aValue != GetPropertySet()->getPropertyValue( "CharOverline" ) ) + { + GetPropertySet()->setPropertyValue( "CharOverline" , aValue ); + bChanged = true; + } + } + + if ( rItem.QueryValue( aValue, MID_TL_COLOR ) ) + { + if ( aValue != GetPropertySet()->getPropertyValue( "CharOverlineColor" ) ) + { + GetPropertySet()->setPropertyValue( "CharOverlineColor" , aValue ); + bChanged = true; + } + } + + if ( rItem.QueryValue( aValue, MID_TL_HASCOLOR ) ) + { + if ( aValue != GetPropertySet()->getPropertyValue( "CharOverlineHasColor" ) ) + { + GetPropertySet()->setPropertyValue( "CharOverlineHasColor" , aValue ); + bChanged = true; + } + } + } + break; + + case EE_CHAR_ITALIC: + case EE_CHAR_ITALIC_CJK: + case EE_CHAR_ITALIC_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_ITALIC_CJK ) + aPostfix = "Asian"; + else if( nWhichId == EE_CHAR_ITALIC_CTL ) + aPostfix = "Complex"; + + const SvxPostureItem & rItem = + static_cast< const SvxPostureItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_POSTURE )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharPosture" + aPostfix)) + { + GetPropertySet()->setPropertyValue( "CharPosture" + aPostfix, aValue ); + bChanged = true; + } + } + } + break; + + case EE_CHAR_WEIGHT: + case EE_CHAR_WEIGHT_CJK: + case EE_CHAR_WEIGHT_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_WEIGHT_CJK ) + aPostfix = "Asian" ; + else if( nWhichId == EE_CHAR_WEIGHT_CTL ) + aPostfix = "Complex"; + + const SvxWeightItem & rItem = + static_cast< const SvxWeightItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_WEIGHT )) + { + if( aValue != GetPropertySet()->getPropertyValue( "CharWeight" + aPostfix)) + { + GetPropertySet()->setPropertyValue( "CharWeight" + aPostfix, aValue ); + bChanged = true; + } + } + } + break; + + case EE_CHAR_FONTHEIGHT: + case EE_CHAR_FONTHEIGHT_CJK: + case EE_CHAR_FONTHEIGHT_CTL: + { + OUString aPostfix; + if( nWhichId == EE_CHAR_FONTHEIGHT_CJK ) + aPostfix = "Asian"; + else if( nWhichId == EE_CHAR_FONTHEIGHT_CTL ) + aPostfix = "Complex"; + + const SvxFontHeightItem & rItem = + static_cast< const SvxFontHeightItem & >( + rItemSet.Get( nWhichId )); + + try + { + if( rItem.QueryValue( aValue, MID_FONTHEIGHT ) ) + { + bool bSetValue = false; + if( aValue != GetPropertySet()->getPropertyValue( "CharHeight" + aPostfix )) + bSetValue = true; + else + { + if (m_pRefSize) + { + awt::Size aNewRefSize = *m_pRefSize; + awt::Size aOldRefSize; + if( GetRefSizePropertySet()->getPropertyValue( m_aRefSizePropertyName ) >>= aOldRefSize ) + { + if( aNewRefSize.Width != aOldRefSize.Width + || aNewRefSize.Height != aOldRefSize.Height ) + bSetValue = true; + } + } + } + if( bSetValue ) + { + // set new reference size only if there was a reference size before (auto-scaling on) + if (m_pRefSize && GetRefSizePropertySet()->getPropertyValue( m_aRefSizePropertyName ).hasValue()) + { + GetRefSizePropertySet()->setPropertyValue( + m_aRefSizePropertyName, uno::Any(*m_pRefSize)); + } + + GetPropertySet()->setPropertyValue( "CharHeight" + aPostfix, aValue ); + bChanged = true; + } + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + break; + } + + return bChanged; +} + +const uno::Reference<beans::XPropertySet>& CharacterPropertyItemConverter::GetRefSizePropertySet() const +{ + return m_xRefSizePropSet; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx new file mode 100644 index 000000000..a6c4c34dc --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/DataPointItemConverter.cxx @@ -0,0 +1,822 @@ +/* -*- 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 <DataPointItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <ItemPropertyMap.hxx> + +#include <GraphicPropertyItemConverter.hxx> +#include <CharacterPropertyItemConverter.hxx> +#include <StatisticsItemConverter.hxx> +#include <SeriesOptionsItemConverter.hxx> +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <DiagramHelper.hxx> +#include <Diagram.hxx> +#include <ChartModel.hxx> +#include <ChartModelHelper.hxx> +#include <ChartType.hxx> +#include <ChartTypeHelper.hxx> +#include <unonames.hxx> + +#include <com/sun/star/chart/DataLabelPlacement.hpp> +#include <com/sun/star/chart2/AxisType.hpp> +#include <com/sun/star/chart2/DataPointLabel.hpp> +#include <com/sun/star/chart2/Symbol.hpp> +#include <com/sun/star/chart2/RelativePosition.hpp> +#include <com/sun/star/chart2/XDataSeries.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <comphelper/sequence.hxx> +#include <svx/xflclit.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <editeng/sizeitem.hxx> +#include <svl/stritem.hxx> +#include <editeng/brushitem.hxx> +#include <svl/ilstitem.hxx> +#include <svx/sdangitm.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/graph.hxx> +#include <rtl/math.hxx> + +#include <svx/tabline.hxx> + +#include <memory> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using ::com::sun::star::uno::Reference; + +namespace chart::wrapper { + +namespace { + +ItemPropertyMapType & lcl_GetDataPointPropertyMap() +{ + static ItemPropertyMapType aDataPointPropertyMap{ + {SCHATTR_STYLE_SHAPE, {"Geometry3D", 0}}}; + return aDataPointPropertyMap; +}; + +sal_Int32 lcl_getSymbolStyleForSymbol( const chart2::Symbol & rSymbol ) +{ + sal_Int32 nStyle = SVX_SYMBOLTYPE_UNKNOWN; + switch( rSymbol.Style ) + { + case chart2::SymbolStyle_NONE: + nStyle = SVX_SYMBOLTYPE_NONE; + break; + case chart2::SymbolStyle_AUTO: + nStyle = SVX_SYMBOLTYPE_AUTO; + break; + case chart2::SymbolStyle_GRAPHIC: + nStyle = SVX_SYMBOLTYPE_BRUSHITEM; + break; + case chart2::SymbolStyle_STANDARD: + nStyle = rSymbol.StandardSymbol; + break; + + case chart2::SymbolStyle_POLYGON: + // to avoid warning + case chart2::SymbolStyle::SymbolStyle_MAKE_FIXED_SIZE: + // nothing + break; + } + return nStyle; +} + +bool lcl_NumberFormatFromItemToPropertySet( sal_uInt16 nWhichId, const SfxItemSet & rItemSet, const uno::Reference< beans::XPropertySet > & xPropertySet, bool bOverwriteAttributedDataPointsAlso ) +{ + bool bChanged = false; + if( !xPropertySet.is() ) + return bChanged; + OUString aPropertyName = (nWhichId==SID_ATTR_NUMBERFORMAT_VALUE) ? OUString(CHART_UNONAME_NUMFMT) : OUString( "PercentageNumberFormat" ); + sal_uInt16 nSourceWhich = (nWhichId==SID_ATTR_NUMBERFORMAT_VALUE) ? SID_ATTR_NUMBERFORMAT_SOURCE : SCHATTR_PERCENT_NUMBERFORMAT_SOURCE; + + if( rItemSet.GetItemState( nSourceWhich ) != SfxItemState::SET ) + return bChanged; + + uno::Any aValue; + bool bUseSourceFormat = static_cast< const SfxBoolItem & >( + rItemSet.Get( nSourceWhich )).GetValue(); + if( !bUseSourceFormat ) + { + SfxItemState aState = rItemSet.GetItemState( nWhichId ); + if( aState == SfxItemState::SET ) + { + sal_Int32 nFmt = static_cast< sal_Int32 >( + static_cast< const SfxUInt32Item & >( + rItemSet.Get( nWhichId )).GetValue()); + aValue <<= nFmt; + } + else + return bChanged; + } + + uno::Any aOldValue( xPropertySet->getPropertyValue(aPropertyName) ); + if( bOverwriteAttributedDataPointsAlso ) + { + Reference< chart2::XDataSeries > xSeries( xPropertySet, uno::UNO_QUERY); + if( aValue != aOldValue || + ::chart::DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, aPropertyName, aOldValue ) ) + { + ::chart::DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, aPropertyName, aValue ); + bChanged = true; + } + } + else if( aOldValue != aValue ) + { + xPropertySet->setPropertyValue(aPropertyName, aValue ); + bChanged = true; + } + return bChanged; +} + +bool lcl_UseSourceFormatFromItemToPropertySet( sal_uInt16 nWhichId, const SfxItemSet & rItemSet, const uno::Reference< beans::XPropertySet > & xPropertySet, bool bOverwriteAttributedDataPointsAlso ) +{ + bool bChanged = false; + if( !xPropertySet.is() ) + return bChanged; + OUString aPropertyName = (nWhichId==SID_ATTR_NUMBERFORMAT_SOURCE) ? OUString(CHART_UNONAME_NUMFMT) : OUString( "PercentageNumberFormat" ); + sal_uInt16 nFormatWhich = (nWhichId==SID_ATTR_NUMBERFORMAT_SOURCE) ? SID_ATTR_NUMBERFORMAT_VALUE : SCHATTR_PERCENT_NUMBERFORMAT_VALUE; + + if( rItemSet.GetItemState( nWhichId ) != SfxItemState::SET ) + return bChanged; + + uno::Any aNewValue; + bool bUseSourceFormat = static_cast< const SfxBoolItem & >( + rItemSet.Get( nWhichId )).GetValue(); + xPropertySet->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::Any(bUseSourceFormat)); + if( !bUseSourceFormat ) + { + SfxItemState aState = rItemSet.GetItemState( nFormatWhich ); + if( aState == SfxItemState::SET ) + { + sal_Int32 nFormatKey = static_cast< sal_Int32 >( + static_cast< const SfxUInt32Item & >( + rItemSet.Get( nFormatWhich )).GetValue()); + aNewValue <<= nFormatKey; + } + else + return bChanged; + } + + uno::Any aOldValue( xPropertySet->getPropertyValue(aPropertyName) ); + if( bOverwriteAttributedDataPointsAlso ) + { + Reference< chart2::XDataSeries > xSeries( xPropertySet, uno::UNO_QUERY); + if( aNewValue != aOldValue || + ::chart::DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, aPropertyName, aOldValue ) ) + { + ::chart::DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, aPropertyName, aNewValue ); + bChanged = true; + } + } + else if( aOldValue != aNewValue ) + { + xPropertySet->setPropertyValue( aPropertyName, aNewValue ); + bChanged = true; + } + + return bChanged; +} + +} // anonymous namespace + +DataPointItemConverter::DataPointItemConverter( + const rtl::Reference<::chart::ChartModel> & xChartModel, + const uno::Reference< uno::XComponentContext > & xContext, + const uno::Reference< beans::XPropertySet > & rPropertySet, + const rtl::Reference< DataSeries > & xSeries, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference<lang::XMultiServiceFactory>& xNamedPropertyContainerFactory, + GraphicObjectType eMapTo, + const awt::Size* pRefSize, + bool bDataSeries, + bool bUseSpecialFillColor, + sal_Int32 nSpecialFillColor, + bool bOverwriteLabelsForAttributedDataPointsAlso, + sal_Int32 nNumberFormat, + sal_Int32 nPercentNumberFormat, + sal_Int32 nPointIndex ) : + ItemConverter( rPropertySet, rItemPool ), + m_bDataSeries( bDataSeries ), + m_bOverwriteLabelsForAttributedDataPointsAlso(m_bDataSeries && bOverwriteLabelsForAttributedDataPointsAlso), + m_bUseSpecialFillColor(bUseSpecialFillColor), + m_nSpecialFillColor(ColorTransparency, nSpecialFillColor), + m_nNumberFormat(nNumberFormat), + m_nPercentNumberFormat(nPercentNumberFormat), + m_bForbidPercentValue(true), + m_bHideLegendEntry(false), + m_nPointIndex(nPointIndex), + m_xSeries(xSeries) +{ + m_aConverters.emplace_back( new GraphicPropertyItemConverter( + rPropertySet, rItemPool, rDrawModel, xNamedPropertyContainerFactory, eMapTo )); + m_aConverters.emplace_back( new CharacterPropertyItemConverter(rPropertySet, rItemPool, pRefSize, "ReferencePageSize")); + if( bDataSeries ) + { + m_aConverters.emplace_back( new StatisticsItemConverter( xChartModel, rPropertySet, rItemPool )); + m_aConverters.emplace_back( new SeriesOptionsItemConverter( xChartModel, xContext, rPropertySet, rItemPool )); + } + + rtl::Reference< Diagram > xDiagram( ChartModelHelper::findDiagram(xChartModel) ); + rtl::Reference< ChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram , xSeries ) ); + bool bFound = false; + bool bAmbiguous = false; + bool bSwapXAndY = DiagramHelper::getVertical( xDiagram, bFound, bAmbiguous ); + m_aAvailableLabelPlacements = ChartTypeHelper::getSupportedLabelPlacements( xChartType, bSwapXAndY, xSeries ); + + m_bForbidPercentValue = ChartTypeHelper::getAxisType( xChartType, 0 ) != AxisType::CATEGORY; + + if (bDataSeries) + return; + + uno::Sequence<sal_Int32> deletedLegendEntriesSeq; + xSeries->getPropertyValue("DeletedLegendEntries") >>= deletedLegendEntriesSeq; + for (const auto& deletedLegendEntry : std::as_const(deletedLegendEntriesSeq)) + { + if (nPointIndex == deletedLegendEntry) + { + m_bHideLegendEntry = true; + break; + } + } +} + +DataPointItemConverter::~DataPointItemConverter() +{ +} + +void DataPointItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + for( const auto& pConv : m_aConverters ) + pConv->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet( rOutItemSet ); + + if( m_bUseSpecialFillColor ) + { + Color aColor(m_nSpecialFillColor); + rOutItemSet.Put( XFillColorItem( OUString(), aColor ) ); + } +} + +bool DataPointItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = false; + + for( const auto& pConv : m_aConverters ) + bResult = pConv->ApplyItemSet( rItemSet ) || bResult; + + // own items + return ItemConverter::ApplyItemSet( rItemSet ) || bResult; +} + +const WhichRangesContainer& DataPointItemConverter::GetWhichPairs() const +{ + // must span all used items! + if( m_bDataSeries ) + return nRowWhichPairs; + return nDataPointWhichPairs; +} + +bool DataPointItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const +{ + ItemPropertyMapType & rMap( lcl_GetDataPointPropertyMap()); + ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId )); + + if( aIt == rMap.end()) + return false; + + rOutProperty =(*aIt).second; + return true; +} + +bool DataPointItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + + switch( nWhichId ) + { + case SCHATTR_DATADESCR_SHOW_NUMBER: + case SCHATTR_DATADESCR_SHOW_PERCENTAGE: + case SCHATTR_DATADESCR_SHOW_CATEGORY: + case SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME: + case SCHATTR_DATADESCR_SHOW_SYMBOL: + { + const SfxBoolItem & rItem = static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )); + + uno::Any aOldValue = GetPropertySet()->getPropertyValue(CHART_UNONAME_LABEL); + chart2::DataPointLabel aLabel; + if( aOldValue >>= aLabel ) + { + sal_Bool& rValue = (nWhichId==SCHATTR_DATADESCR_SHOW_NUMBER) ? aLabel.ShowNumber : ( + (nWhichId==SCHATTR_DATADESCR_SHOW_PERCENTAGE) ? aLabel.ShowNumberInPercent : ( + (nWhichId==SCHATTR_DATADESCR_SHOW_CATEGORY) ? aLabel.ShowCategoryName : ( + (nWhichId==SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME) ? aLabel.ShowSeriesName : aLabel.ShowLegendSymbol ))); + bool bOldValue = rValue; + rValue = rItem.GetValue(); + if( m_bOverwriteLabelsForAttributedDataPointsAlso ) + { + Reference< chart2::XDataSeries > xSeries( GetPropertySet(), uno::UNO_QUERY); + if( bOldValue != bool(rValue) || + DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, CHART_UNONAME_LABEL , aOldValue ) ) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, CHART_UNONAME_LABEL , uno::Any( aLabel ) ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, CHART_UNONAME_CUSTOM_LABEL_FIELDS, uno::Any() ); + bChanged = true; + } + } + else if( bOldValue != bool(rValue) ) + { + GetPropertySet()->setPropertyValue(CHART_UNONAME_LABEL , uno::Any(aLabel)); + bChanged = true; + } + } + } + break; + + case SID_ATTR_NUMBERFORMAT_VALUE: + case SCHATTR_PERCENT_NUMBERFORMAT_VALUE: //fall through intended + { + bChanged = lcl_NumberFormatFromItemToPropertySet( nWhichId, rItemSet, GetPropertySet(), m_bOverwriteLabelsForAttributedDataPointsAlso ); + } + break; + + case SID_ATTR_NUMBERFORMAT_SOURCE: + case SCHATTR_PERCENT_NUMBERFORMAT_SOURCE: //fall through intended + { + bChanged = lcl_UseSourceFormatFromItemToPropertySet( nWhichId, rItemSet, GetPropertySet(), m_bOverwriteLabelsForAttributedDataPointsAlso ); + } + break; + + case SCHATTR_DATADESCR_SEPARATOR: + { + OUString aNewValue = static_cast< const SfxStringItem & >( rItemSet.Get( nWhichId )).GetValue(); + try + { + OUString aOldValue; + GetPropertySet()->getPropertyValue( "LabelSeparator" ) >>= aOldValue; + if( m_bOverwriteLabelsForAttributedDataPointsAlso ) + { + Reference< chart2::XDataSeries > xSeries( GetPropertySet(), uno::UNO_QUERY); + if( aOldValue != aNewValue || + DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, "LabelSeparator" , uno::Any( aOldValue ) ) ) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "LabelSeparator" , uno::Any( aNewValue ) ); + bChanged = true; + } + } + else if( aOldValue != aNewValue ) + { + GetPropertySet()->setPropertyValue( "LabelSeparator" , uno::Any( aNewValue )); + bChanged = true; + } + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + + case SCHATTR_DATADESCR_WRAP_TEXT: + { + + try + { + bool bNew = static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue(); + bool bOld = false; + GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bOld; + if( m_bOverwriteLabelsForAttributedDataPointsAlso ) + { + Reference< chart2::XDataSeries > xSeries( GetPropertySet(), uno::UNO_QUERY); + if( bOld!=bNew || + DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, "TextWordWrap", uno::Any( bOld ) ) ) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "TextWordWrap", uno::Any( bNew ) ); + bChanged = true; + } + } + else if( bOld!=bNew ) + { + GetPropertySet()->setPropertyValue( "TextWordWrap", uno::Any( bNew )); + bChanged = true; + } + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + + case SCHATTR_DATADESCR_PLACEMENT: + { + + try + { + sal_Int32 nNew = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue(); + sal_Int32 nOld = -1; + RelativePosition aCustomLabelPosition; + GetPropertySet()->getPropertyValue("LabelPlacement") >>= nOld; + if( m_bOverwriteLabelsForAttributedDataPointsAlso ) + { + Reference< chart2::XDataSeries > xSeries( GetPropertySet(), uno::UNO_QUERY); + if( nOld!=nNew || + DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, "LabelPlacement" , uno::Any( nOld ) ) ) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "LabelPlacement" , uno::Any( nNew ) ); + bChanged = true; + } + } + else if( nOld!=nNew || (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition) ) + { + GetPropertySet()->setPropertyValue("LabelPlacement", uno::Any(nNew)); + GetPropertySet()->setPropertyValue("CustomLabelPosition", uno::Any()); + bChanged = true; + } + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + + case SCHATTR_STYLE_SYMBOL: + { + sal_Int32 nStyle = + static_cast< const SfxInt32Item & >( + rItemSet.Get( nWhichId )).GetValue(); + chart2::Symbol aSymbol; + + GetPropertySet()->getPropertyValue( "Symbol" ) >>= aSymbol; + sal_Int32 nOldStyle = lcl_getSymbolStyleForSymbol( aSymbol ); + + if( nStyle != nOldStyle ) + { + bool bDeleteSymbol = false; + switch( nStyle ) + { + case SVX_SYMBOLTYPE_NONE: + aSymbol.Style = chart2::SymbolStyle_NONE; + break; + case SVX_SYMBOLTYPE_AUTO: + aSymbol.Style = chart2::SymbolStyle_AUTO; + break; + case SVX_SYMBOLTYPE_BRUSHITEM: + aSymbol.Style = chart2::SymbolStyle_GRAPHIC; + break; + case SVX_SYMBOLTYPE_UNKNOWN: + bDeleteSymbol = true; + break; + + default: + aSymbol.Style = chart2::SymbolStyle_STANDARD; + aSymbol.StandardSymbol = nStyle; + } + + if( bDeleteSymbol ) + GetPropertySet()->setPropertyValue( "Symbol" , uno::Any()); + else + GetPropertySet()->setPropertyValue( "Symbol" , uno::Any( aSymbol )); + bChanged = true; + } + } + break; + + case SCHATTR_SYMBOL_SIZE: + { + Size aSize = static_cast< const SvxSizeItem & >( + rItemSet.Get( nWhichId )).GetSize(); + chart2::Symbol aSymbol; + + GetPropertySet()->getPropertyValue( "Symbol" ) >>= aSymbol; + if( aSize.getWidth() != aSymbol.Size.Width || + aSize.getHeight() != aSymbol.Size.Height ) + { + aSymbol.Size.Width = aSize.getWidth(); + aSymbol.Size.Height = aSize.getHeight(); + + GetPropertySet()->setPropertyValue( "Symbol" , uno::Any( aSymbol )); + bChanged = true; + } + } + break; + + case SCHATTR_SYMBOL_BRUSH: + { + const SvxBrushItem & rBrshItem( static_cast< const SvxBrushItem & >( + rItemSet.Get( nWhichId ))); + uno::Any aXGraphicAny; + const Graphic *pGraphic( rBrshItem.GetGraphic()); + if( pGraphic ) + { + uno::Reference< graphic::XGraphic > xGraphic( pGraphic->GetXGraphic()); + if( xGraphic.is()) + { + aXGraphicAny <<= xGraphic; + chart2::Symbol aSymbol; + GetPropertySet()->getPropertyValue( "Symbol" ) >>= aSymbol; + if( aSymbol.Graphic != xGraphic ) + { + aSymbol.Graphic = xGraphic; + GetPropertySet()->setPropertyValue( "Symbol" , uno::Any( aSymbol )); + bChanged = true; + } + } + } + } + break; + + case SCHATTR_TEXT_DEGREES: + { + double fValue = toDegrees(rItemSet.Get(SCHATTR_TEXT_DEGREES).GetValue()); + double fOldValue = 0.0; + bool bPropExisted = + ( GetPropertySet()->getPropertyValue( "TextRotation" ) >>= fOldValue ); + + if( ! bPropExisted || fOldValue != fValue ) + { + GetPropertySet()->setPropertyValue( "TextRotation" , uno::Any( fValue )); + bChanged = true; + } + } + break; + + case SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY: + { + bool bHideLegendEntry = static_cast<const SfxBoolItem &>(rItemSet.Get(nWhichId)).GetValue(); + if (bHideLegendEntry != m_bHideLegendEntry) + { + uno::Sequence<sal_Int32> deletedLegendEntriesSeq; + m_xSeries->getPropertyValue("DeletedLegendEntries") >>= deletedLegendEntriesSeq; + std::vector<sal_Int32> deletedLegendEntries; + for (const auto& deletedLegendEntry : std::as_const(deletedLegendEntriesSeq)) + { + if (bHideLegendEntry || m_nPointIndex != deletedLegendEntry) + deletedLegendEntries.push_back(deletedLegendEntry); + } + if (bHideLegendEntry) + deletedLegendEntries.push_back(m_nPointIndex); + m_xSeries->setPropertyValue("DeletedLegendEntries", uno::Any(comphelper::containerToSequence(deletedLegendEntries))); + } + } + break; + + case SCHATTR_DATADESCR_CUSTOM_LEADER_LINES: + { + try + { + bool bNew = static_cast<const SfxBoolItem&>(rItemSet.Get(nWhichId)).GetValue(); + bool bOld = true; + if( (m_xSeries->getPropertyValue("ShowCustomLeaderLines") >>= bOld) && bOld != bNew ) + { + m_xSeries->setPropertyValue("ShowCustomLeaderLines", uno::Any(bNew)); + bChanged = true; + } + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + } + break; + } + + return bChanged; +} + +void DataPointItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case SCHATTR_DATADESCR_SHOW_NUMBER: + case SCHATTR_DATADESCR_SHOW_PERCENTAGE: + case SCHATTR_DATADESCR_SHOW_CATEGORY: + case SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME: + case SCHATTR_DATADESCR_SHOW_SYMBOL: + { + chart2::DataPointLabel aLabel; + if (GetPropertySet()->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel) + { + bool bValue = (nWhichId==SCHATTR_DATADESCR_SHOW_NUMBER) ? aLabel.ShowNumber : ( + (nWhichId==SCHATTR_DATADESCR_SHOW_PERCENTAGE) ? aLabel.ShowNumberInPercent : ( + (nWhichId==SCHATTR_DATADESCR_SHOW_CATEGORY) ? aLabel.ShowCategoryName : ( + (nWhichId==SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME) ? aLabel.ShowSeriesName : aLabel.ShowLegendSymbol ))); + + rOutItemSet.Put( SfxBoolItem( nWhichId, bValue )); + + if( m_bOverwriteLabelsForAttributedDataPointsAlso ) + { + if( DataSeriesHelper::hasAttributedDataPointDifferentValue( + Reference< chart2::XDataSeries >( GetPropertySet(), uno::UNO_QUERY), CHART_UNONAME_LABEL , uno::Any(aLabel) ) ) + { + rOutItemSet.InvalidateItem(nWhichId); + } + } + } + } + break; + + case SID_ATTR_NUMBERFORMAT_VALUE: + { + sal_Int32 nKey = 0; + if (!(GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nKey)) + nKey = m_nNumberFormat; + rOutItemSet.Put( SfxUInt32Item( nWhichId, nKey )); + } + break; + + case SCHATTR_PERCENT_NUMBERFORMAT_VALUE: + { + sal_Int32 nKey = 0; + if( !(GetPropertySet()->getPropertyValue( "PercentageNumberFormat" ) >>= nKey) ) + nKey = m_nPercentNumberFormat; + rOutItemSet.Put( SfxUInt32Item( nWhichId, nKey )); + } + break; + + case SID_ATTR_NUMBERFORMAT_SOURCE: + { + bool bUseSourceFormat = false; + try + { + GetPropertySet()->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT) >>= bUseSourceFormat; + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + bool bNumberFormatIsSet = GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT).hasValue() && !bUseSourceFormat; + rOutItemSet.Put( SfxBoolItem( nWhichId, ! bNumberFormatIsSet )); + } + break; + case SCHATTR_PERCENT_NUMBERFORMAT_SOURCE: + { + bool bUseSourceFormat = false; + try + { + GetPropertySet()->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT) >>= bUseSourceFormat; + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + bool bNumberFormatIsSet = GetPropertySet()->getPropertyValue( "PercentageNumberFormat" ).hasValue() && !bUseSourceFormat; + rOutItemSet.Put( SfxBoolItem( nWhichId, ! bNumberFormatIsSet )); + } + break; + + case SCHATTR_DATADESCR_SEPARATOR: + { + try + { + OUString aValue; + GetPropertySet()->getPropertyValue( "LabelSeparator" ) >>= aValue; + rOutItemSet.Put( SfxStringItem( nWhichId, aValue )); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + + case SCHATTR_DATADESCR_WRAP_TEXT: + { + try + { + bool bValue = false; + GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bValue; + rOutItemSet.Put( SfxBoolItem( nWhichId, bValue )); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + + case SCHATTR_DATADESCR_PLACEMENT: + { + try + { + sal_Int32 nPlacement=0; + RelativePosition aCustomLabelPosition; + if( !m_bOverwriteLabelsForAttributedDataPointsAlso && (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition) ) + rOutItemSet.Put(SfxInt32Item(nWhichId, css::chart::DataLabelPlacement::CUSTOM)); + else if( GetPropertySet()->getPropertyValue( "LabelPlacement" ) >>= nPlacement ) + rOutItemSet.Put( SfxInt32Item( nWhichId, nPlacement )); + else if( m_aAvailableLabelPlacements.hasElements() ) + rOutItemSet.Put( SfxInt32Item( nWhichId, m_aAvailableLabelPlacements[0] )); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + + case SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS: + { + rOutItemSet.Put( SfxIntegerListItem( nWhichId, m_aAvailableLabelPlacements ) ); + } + break; + + case SCHATTR_DATADESCR_NO_PERCENTVALUE: + { + rOutItemSet.Put( SfxBoolItem( nWhichId, m_bForbidPercentValue )); + } + break; + + case SCHATTR_DATADESCR_CUSTOM_LEADER_LINES: + { + try + { + bool bValue = true; + if( m_xSeries->getPropertyValue( "ShowCustomLeaderLines" ) >>= bValue ) + rOutItemSet.Put(SfxBoolItem(nWhichId, bValue)); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + } + break; + + case SCHATTR_STYLE_SYMBOL: + { + chart2::Symbol aSymbol; + if( GetPropertySet()->getPropertyValue( "Symbol" ) >>= aSymbol ) + rOutItemSet.Put( SfxInt32Item( nWhichId, lcl_getSymbolStyleForSymbol( aSymbol ) )); + } + break; + + case SCHATTR_SYMBOL_SIZE: + { + chart2::Symbol aSymbol; + if( GetPropertySet()->getPropertyValue( "Symbol" ) >>= aSymbol ) + rOutItemSet.Put( + SvxSizeItem( nWhichId, Size( aSymbol.Size.Width, aSymbol.Size.Height ) )); + } + break; + + case SCHATTR_SYMBOL_BRUSH: + { + chart2::Symbol aSymbol; + if(( GetPropertySet()->getPropertyValue( "Symbol" ) >>= aSymbol ) + && aSymbol.Graphic.is() ) + { + rOutItemSet.Put( SvxBrushItem( Graphic( aSymbol.Graphic ), GPOS_MM, SCHATTR_SYMBOL_BRUSH )); + } + } + break; + + case SCHATTR_TEXT_DEGREES: + { + double fValue = 0; + + if( GetPropertySet()->getPropertyValue( "TextRotation" ) >>= fValue ) + { + rOutItemSet.Put( SdrAngleItem( SCHATTR_TEXT_DEGREES, Degree100(static_cast< sal_Int32 >( + ::rtl::math::round( fValue * 100.0 ) ) ))); + } + } + break; + + case SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY: + { + rOutItemSet.Put(SfxBoolItem(nWhichId, m_bHideLegendEntry)); + break; + } + break; + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/ErrorBarItemConverter.cxx b/chart2/source/controller/itemsetwrapper/ErrorBarItemConverter.cxx new file mode 100644 index 000000000..8e23902f6 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/ErrorBarItemConverter.cxx @@ -0,0 +1,433 @@ +/* -*- 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 <ErrorBarItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <StatisticsHelper.hxx> + +#include <GraphicPropertyItemConverter.hxx> + +#include <svl/stritem.hxx> +#include <svx/chrtitem.hxx> +#include <rtl/math.hxx> + +#include <com/sun/star/chart2/XInternalDataProvider.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart/ErrorBarStyle.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +namespace +{ + +void lcl_getErrorValues( const uno::Reference< beans::XPropertySet > & xErrorBarProp, + double & rOutPosError, double & rOutNegError ) +{ + if( ! xErrorBarProp.is()) + return; + + try + { + xErrorBarProp->getPropertyValue( "PositiveError" ) >>= rOutPosError; + xErrorBarProp->getPropertyValue( "NegativeError" ) >>= rOutNegError; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void lcl_getErrorIndicatorValues( + const uno::Reference< beans::XPropertySet > & xErrorBarProp, + bool & rOutShowPosError, bool & rOutShowNegError ) +{ + if( ! xErrorBarProp.is()) + return; + + try + { + xErrorBarProp->getPropertyValue( "ShowPositiveError" ) >>= rOutShowPosError; + xErrorBarProp->getPropertyValue( "ShowNegativeError" ) >>= rOutShowNegError; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +} // anonymous namespace + +namespace chart::wrapper +{ + +ErrorBarItemConverter::ErrorBarItemConverter( + const uno::Reference< frame::XModel > & xModel, + const uno::Reference< beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory ) : + ItemConverter( rPropertySet, rItemPool ), + m_spGraphicConverter( std::make_shared<GraphicPropertyItemConverter>( + rPropertySet, rItemPool, rDrawModel, + xNamedPropertyContainerFactory, + GraphicObjectType::LineProperties )), + m_xModel( xModel ) +{} + +ErrorBarItemConverter::~ErrorBarItemConverter() +{} + +void ErrorBarItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + m_spGraphicConverter->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet( rOutItemSet ); +} + +bool ErrorBarItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = m_spGraphicConverter->ApplyItemSet( rItemSet ); + + // own items + return ItemConverter::ApplyItemSet( rItemSet ) || bResult; +} + +const WhichRangesContainer& ErrorBarItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nErrorBarWhichPairs; +} + +bool ErrorBarItemConverter::GetItemProperty( + tWhichIdType /* nWhichId */, + tPropertyNameWithMemberId & /* rOutProperty */ ) const +{ + return false; +} + +bool ErrorBarItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + + switch( nWhichId ) + { + // Attention !!! This case must be passed before SCHATTR_STAT_PERCENT, + // SCHATTR_STAT_BIGERROR, SCHATTR_STAT_CONSTPLUS, + // SCHATTR_STAT_CONSTMINUS and SCHATTR_STAT_INDICATE + case SCHATTR_STAT_KIND_ERROR: + { + uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet()); + + SvxChartKindError eErrorKind = + static_cast< const SvxChartKindErrorItem & >( + rItemSet.Get( nWhichId )).GetValue(); + + if( !xErrorBarProp.is() && eErrorKind == SvxChartKindError::NONE) + { + //nothing to do + } + else + { + sal_Int32 nStyle = css::chart::ErrorBarStyle::NONE; + + switch( eErrorKind ) + { + case SvxChartKindError::NONE: + nStyle = css::chart::ErrorBarStyle::NONE; break; + case SvxChartKindError::Variant: + nStyle = css::chart::ErrorBarStyle::VARIANCE; break; + case SvxChartKindError::Sigma: + nStyle = css::chart::ErrorBarStyle::STANDARD_DEVIATION; break; + case SvxChartKindError::Percent: + nStyle = css::chart::ErrorBarStyle::RELATIVE; break; + case SvxChartKindError::BigError: + nStyle = css::chart::ErrorBarStyle::ERROR_MARGIN; break; + case SvxChartKindError::Const: + nStyle = css::chart::ErrorBarStyle::ABSOLUTE; break; + case SvxChartKindError::StdError: + nStyle = css::chart::ErrorBarStyle::STANDARD_ERROR; break; + case SvxChartKindError::Range: + nStyle = css::chart::ErrorBarStyle::FROM_DATA; break; + } + + xErrorBarProp->setPropertyValue( "ErrorBarStyle" , uno::Any( nStyle )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_PERCENT: + case SCHATTR_STAT_BIGERROR: + { + OSL_FAIL( "Deprecated item" ); + uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet()); + + double fValue = + static_cast< const SvxDoubleItem & >( + rItemSet.Get( nWhichId )).GetValue(); + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + + if( ! ( ::rtl::math::approxEqual( fPos, fValue ) && + ::rtl::math::approxEqual( fNeg, fValue ))) + { + xErrorBarProp->setPropertyValue( "PositiveError" , uno::Any( fValue )); + xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_CONSTPLUS: + { + double fValue = + static_cast< const SvxDoubleItem & >( + rItemSet.Get( nWhichId )).GetValue(); + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( GetPropertySet(), fPos, fNeg ); + + if( ! ::rtl::math::approxEqual( fPos, fValue )) + { + GetPropertySet()->setPropertyValue( "PositiveError" , uno::Any( fValue )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_CONSTMINUS: + { + uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet()); + + double fValue = + static_cast< const SvxDoubleItem & >( + rItemSet.Get( nWhichId )).GetValue(); + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + + if( ! ::rtl::math::approxEqual( fNeg, fValue )) + { + xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_INDICATE: + { + uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet()); + + SvxChartIndicate eIndicate = + static_cast< const SvxChartIndicateItem & >( + rItemSet.Get( nWhichId )).GetValue(); + + bool bNewIndPos = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Up ); + bool bNewIndNeg = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Down ); + + bool bShowPos(false), bShowNeg(false); + lcl_getErrorIndicatorValues( xErrorBarProp, bShowPos, bShowNeg ); + + if( bShowPos != bNewIndPos || + bShowNeg != bNewIndNeg ) + { + xErrorBarProp->setPropertyValue( "ShowPositiveError" , uno::Any( bNewIndPos )); + xErrorBarProp->setPropertyValue( "ShowNegativeError" , uno::Any( bNewIndNeg )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_RANGE_POS: + case SCHATTR_STAT_RANGE_NEG: + { + // @todo: also be able to deal with x-error bars + const bool bYError = + rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + + uno::Reference< chart2::data::XDataSource > xErrorBarSource( GetPropertySet(), uno::UNO_QUERY ); + uno::Reference< chart2::XChartDocument > xChartDoc( m_xModel, uno::UNO_QUERY ); + uno::Reference< chart2::data::XDataProvider > xDataProvider; + + if( xChartDoc.is()) + xDataProvider.set( xChartDoc->getDataProvider()); + if( xErrorBarSource.is() && xDataProvider.is()) + { + OUString aNewRange( static_cast< const SfxStringItem & >( rItemSet.Get( nWhichId )).GetValue()); + bool bApplyNewRange = false; + + bool bIsPositiveValue( nWhichId == SCHATTR_STAT_RANGE_POS ); + if( xChartDoc->hasInternalDataProvider()) + { + if( !aNewRange.isEmpty()) + { + uno::Reference< chart2::data::XDataSequence > xSeq( + StatisticsHelper::getErrorDataSequenceFromDataSource( + xErrorBarSource, bIsPositiveValue, bYError )); + if( ! xSeq.is()) + { + // no data range for error bars yet => create + uno::Reference< chart2::XInternalDataProvider > xIntDataProvider( xDataProvider, uno::UNO_QUERY ); + OSL_ASSERT( xIntDataProvider.is()); + if( xIntDataProvider.is()) + { + xIntDataProvider->appendSequence(); + aNewRange = "last"; + bApplyNewRange = true; + } + } + } + } + else + { + uno::Reference< chart2::data::XDataSequence > xSeq( + StatisticsHelper::getErrorDataSequenceFromDataSource( + xErrorBarSource, bIsPositiveValue, bYError )); + bApplyNewRange = + ! ( xSeq.is() && (aNewRange == xSeq->getSourceRangeRepresentation())); + } + + if( bApplyNewRange ) + StatisticsHelper::setErrorDataSequence( + xErrorBarSource, xDataProvider, aNewRange, bIsPositiveValue, bYError ); + } + } + break; + } + + return bChanged; +} + +void ErrorBarItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case SCHATTR_STAT_KIND_ERROR: + { + SvxChartKindError eErrorKind = SvxChartKindError::NONE; + uno::Reference< beans::XPropertySet > xErrorBarProp( GetPropertySet()); + + sal_Int32 nStyle = 0; + if( xErrorBarProp->getPropertyValue( "ErrorBarStyle" ) >>= nStyle ) + { + switch( nStyle ) + { + case css::chart::ErrorBarStyle::NONE: + break; + case css::chart::ErrorBarStyle::VARIANCE: + eErrorKind = SvxChartKindError::Variant; break; + case css::chart::ErrorBarStyle::STANDARD_DEVIATION: + eErrorKind = SvxChartKindError::Sigma; break; + case css::chart::ErrorBarStyle::ABSOLUTE: + eErrorKind = SvxChartKindError::Const; break; + case css::chart::ErrorBarStyle::RELATIVE: + eErrorKind = SvxChartKindError::Percent; break; + case css::chart::ErrorBarStyle::ERROR_MARGIN: + eErrorKind = SvxChartKindError::BigError; break; + case css::chart::ErrorBarStyle::STANDARD_ERROR: + eErrorKind = SvxChartKindError::StdError; break; + case css::chart::ErrorBarStyle::FROM_DATA: + eErrorKind = SvxChartKindError::Range; break; + } + } + rOutItemSet.Put( SvxChartKindErrorItem( eErrorKind, SCHATTR_STAT_KIND_ERROR )); + } + break; + + case SCHATTR_STAT_PERCENT: + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( GetPropertySet(), fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, SCHATTR_STAT_PERCENT )); + } + break; + + case SCHATTR_STAT_BIGERROR: + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( GetPropertySet(), fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, SCHATTR_STAT_BIGERROR )); + } + break; + + case SCHATTR_STAT_CONSTPLUS: + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( GetPropertySet(), fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( fPos, SCHATTR_STAT_CONSTPLUS )); + } + break; + + case SCHATTR_STAT_CONSTMINUS: + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( GetPropertySet(), fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( fNeg, SCHATTR_STAT_CONSTMINUS )); + } + break; + + case SCHATTR_STAT_INDICATE: + { + SvxChartIndicate eIndicate = SvxChartIndicate::Both; + bool bShowPos(false), bShowNeg(false); + lcl_getErrorIndicatorValues( GetPropertySet(), bShowPos, bShowNeg ); + + if( bShowPos ) + { + if( bShowNeg ) + eIndicate = SvxChartIndicate::Both; + else + eIndicate = SvxChartIndicate::Up; + } + else + { + if( bShowNeg ) + eIndicate = SvxChartIndicate::Down; + else + eIndicate = SvxChartIndicate::NONE; + } + rOutItemSet.Put( SvxChartIndicateItem( eIndicate, SCHATTR_STAT_INDICATE )); + } + break; + + case SCHATTR_STAT_RANGE_POS: + case SCHATTR_STAT_RANGE_NEG: + { + const bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + + uno::Reference< chart2::data::XDataSource > xErrorBarSource( GetPropertySet(), uno::UNO_QUERY ); + if( xErrorBarSource.is()) + { + uno::Reference< chart2::data::XDataSequence > xSeq( + StatisticsHelper::getErrorDataSequenceFromDataSource( + xErrorBarSource, (nWhichId == SCHATTR_STAT_RANGE_POS), bYError )); + if( xSeq.is()) + rOutItemSet.Put( SfxStringItem( nWhichId, xSeq->getSourceRangeRepresentation())); + } + } + break; + } +} + +} // namespace chart::wrapper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx b/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx new file mode 100644 index 000000000..e265e4198 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx @@ -0,0 +1,751 @@ +/* -*- 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 <GraphicPropertyItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <ItemPropertyMap.hxx> +#include <PropertyHelper.hxx> +#include <CommonConverters.hxx> +#include <editeng/memberids.h> +#include <svx/unomid.hxx> +#include <svx/xflbmtit.hxx> +#include <svx/xflbstit.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xlndsit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xfltrit.hxx> +#include <svx/xlntrit.hxx> +#include <svx/xgrscit.hxx> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/drawing/BitmapMode.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +namespace chart::wrapper { + +namespace { + +ItemPropertyMapType & lcl_GetDataPointFilledPropertyMap() +{ + static ItemPropertyMapType aDataPointPropertyFilledMap{ + {XATTR_FILLSTYLE, {"FillStyle", 0}}, + {XATTR_FILLCOLOR, {"Color", 0}}, + {XATTR_LINECOLOR, {"BorderColor", 0}}, + {XATTR_LINESTYLE, {"BorderStyle", 0}}, + {XATTR_LINEWIDTH, {"BorderWidth", 0}}, + {XATTR_FILLBACKGROUND, {"FillBackground", 0}}, + {XATTR_FILLBMP_POS, {"FillBitmapRectanglePoint", 0}}, + {XATTR_FILLBMP_SIZEX, {"FillBitmapSizeX", 0}}, + {XATTR_FILLBMP_SIZEY, {"FillBitmapSizeY", 0}}, + {XATTR_FILLBMP_SIZELOG, {"FillBitmapLogicalSize", 0}}, + {XATTR_FILLBMP_TILEOFFSETX, {"FillBitmapOffsetX", 0}}, + {XATTR_FILLBMP_TILEOFFSETY, {"FillBitmapOffsetY", 0}}, + {XATTR_FILLBMP_POSOFFSETX, {"FillBitmapPositionOffsetX", 0}}, + {XATTR_FILLBMP_POSOFFSETY, {"FillBitmapPositionOffsetY", 0}}}; + return aDataPointPropertyFilledMap; +} +ItemPropertyMapType & lcl_GetDataPointLinePropertyMap() +{ + static ItemPropertyMapType aDataPointPropertyLineMap{ + {XATTR_LINECOLOR, {"Color", 0}}, + {XATTR_LINESTYLE, {"LineStyle", 0}}, + {XATTR_LINEWIDTH, {"LineWidth", 0}}, + {XATTR_LINECAP, {"LineCap", 0}}}; + return aDataPointPropertyLineMap; +} +ItemPropertyMapType & lcl_GetLinePropertyMap() +{ + static ItemPropertyMapType aLinePropertyMap{ + {XATTR_LINESTYLE, {"LineStyle", 0}}, + {XATTR_LINEWIDTH, {"LineWidth", 0}}, + {XATTR_LINECOLOR, {"LineColor", 0}}, + {XATTR_LINEJOINT, {"LineJoint", 0}}, + {XATTR_LINECAP, {"LineCap", 0}}}; + return aLinePropertyMap; +} +ItemPropertyMapType & lcl_GetFillPropertyMap() +{ + static ItemPropertyMapType aFillPropertyMap{ + {XATTR_FILLSTYLE, {"FillStyle", 0}}, + {XATTR_FILLCOLOR, {"FillColor", 0}}, + {XATTR_FILLBACKGROUND, {"FillBackground", 0}}, + {XATTR_FILLBMP_POS, {"FillBitmapRectanglePoint", 0}}, + {XATTR_FILLBMP_SIZEX, {"FillBitmapSizeX", 0}}, + {XATTR_FILLBMP_SIZEY, {"FillBitmapSizeY", 0}}, + {XATTR_FILLBMP_SIZELOG, {"FillBitmapLogicalSize", 0}}, + {XATTR_FILLBMP_TILEOFFSETX, {"FillBitmapOffsetX", 0}}, + {XATTR_FILLBMP_TILEOFFSETY, {"FillBitmapOffsetY", 0}}, + {XATTR_FILLBMP_POSOFFSETX, {"FillBitmapPositionOffsetX", 0}}, + {XATTR_FILLBMP_POSOFFSETY, {"FillBitmapPositionOffsetY", 0}}}; + return aFillPropertyMap; +} + +bool lcl_supportsFillProperties( ::chart::wrapper::GraphicObjectType eType ) +{ + return ( eType == ::chart::wrapper::GraphicObjectType::FilledDataPoint || + eType == ::chart::wrapper::GraphicObjectType::LineAndFillProperties ); +} + +bool lcl_SetContentForNamedProperty( + const uno::Reference< lang::XMultiServiceFactory > & xFactory, + const OUString & rTableName, + NameOrIndex & rItem, sal_uInt8 nMemberId ) +{ + bool bResult = false; + if( xFactory.is()) + { + OUString aPropertyValue( rItem.GetName()); + uno::Reference< container::XNameAccess > xNameAcc( + xFactory->createInstance( rTableName ), + uno::UNO_QUERY ); + if( xNameAcc.is() && + xNameAcc->hasByName( aPropertyValue )) + { + rItem.PutValue( xNameAcc->getByName( aPropertyValue ), nMemberId ); + bResult = true; + } + } + return bResult; +} + +} // anonymous namespace + +GraphicPropertyItemConverter::GraphicPropertyItemConverter( + const uno::Reference< + beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory, + GraphicObjectType eObjectType /* = FILL_PROPERTIES */ ) : + ItemConverter( rPropertySet, rItemPool ), + m_GraphicObjectType( eObjectType ), + m_rDrawModel( rDrawModel ), + m_xNamedPropertyTableFactory( xNamedPropertyContainerFactory ) +{} + +GraphicPropertyItemConverter::~GraphicPropertyItemConverter() +{} + +const WhichRangesContainer& GraphicPropertyItemConverter::GetWhichPairs() const +{ + switch( m_GraphicObjectType ) + { + case GraphicObjectType::LineDataPoint: + case GraphicObjectType::FilledDataPoint: + return nRowWhichPairs; + case GraphicObjectType::LineProperties: + return nLinePropertyWhichPairs; + case GraphicObjectType::LineAndFillProperties: + return nLineAndFillPropertyWhichPairs; + } + + static const WhichRangesContainer empty; + return empty; +} + +bool GraphicPropertyItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const +{ + ItemPropertyMapType::const_iterator aEndIt; + ItemPropertyMapType::const_iterator aIt; + + switch( m_GraphicObjectType ) + { + case GraphicObjectType::LineDataPoint: + aEndIt = lcl_GetDataPointLinePropertyMap().end(); + aIt = lcl_GetDataPointLinePropertyMap().find( nWhichId ); + break; + case GraphicObjectType::FilledDataPoint: + aEndIt = lcl_GetDataPointFilledPropertyMap().end(); + aIt = lcl_GetDataPointFilledPropertyMap().find( nWhichId ); + break; + case GraphicObjectType::LineProperties: + aEndIt = lcl_GetLinePropertyMap().end(); + aIt = lcl_GetLinePropertyMap().find( nWhichId ); + break; + + case GraphicObjectType::LineAndFillProperties: + // line + aEndIt = lcl_GetLinePropertyMap().end(); + aIt = lcl_GetLinePropertyMap().find( nWhichId ); + + // not found => try fill + if( aIt == aEndIt ) + { + aEndIt = lcl_GetFillPropertyMap().end(); + aIt = lcl_GetFillPropertyMap().find( nWhichId ); + } + break; + } + + if( aIt == aEndIt ) + return false; + + rOutProperty =(*aIt).second; + return true; +} + +void GraphicPropertyItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + // bitmap property + case XATTR_FILLBMP_TILE: + case XATTR_FILLBMP_STRETCH: + { + drawing::BitmapMode aMode = drawing::BitmapMode_REPEAT; + if( GetPropertySet()->getPropertyValue( "FillBitmapMode" ) >>= aMode ) + { + rOutItemSet.Put( XFillBmpTileItem( aMode == drawing::BitmapMode_REPEAT )); + rOutItemSet.Put( XFillBmpStretchItem( aMode == drawing::BitmapMode_STRETCH )); + } + } + break; + + case XATTR_FILLFLOATTRANSPARENCE: + try + { + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "TransparencyGradientName" ) + : OUString( "FillTransparenceGradientName" ); + + uno::Any aValue( GetPropertySet()->getPropertyValue( aPropName )); + if( aValue.hasValue()) + { + XFillFloatTransparenceItem aItem; + aItem.PutValue( aValue, MID_NAME ); + + lcl_SetContentForNamedProperty( + m_xNamedPropertyTableFactory, "com.sun.star.drawing.TransparencyGradientTable" , + aItem, MID_FILLGRADIENT ); + + // this is important to enable the item + OUString aName; + if( (aValue >>= aName) && + !aName.isEmpty()) + { + aItem.SetEnabled( true ); + rOutItemSet.Put( aItem ); + } + } + } + } + catch( const beans::UnknownPropertyException & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + break; + + case XATTR_GRADIENTSTEPCOUNT: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "GradientStepCount" ) + : OUString( "FillGradientStepCount" ); + + uno::Any aValue( GetPropertySet()->getPropertyValue( aPropName ) ); + if( hasLongOrShortValue(aValue) ) + { + sal_Int16 nStepCount = getShortForLongAlso(aValue); + rOutItemSet.Put( XGradientStepCountItem( nStepCount )); + } + } + break; + + case XATTR_LINEDASH: + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "BorderDashName" ) + : OUString( "LineDashName" ); + + XLineDashItem aItem; + aItem.PutValue( GetPropertySet()->getPropertyValue( aPropName ), MID_NAME ); + + lcl_SetContentForNamedProperty( + m_xNamedPropertyTableFactory, "com.sun.star.drawing.DashTable" , + aItem, MID_LINEDASH ); + + // translate model name to UI-name for predefined entries, so + // that the correct entry is chosen in the list of UI-names + std::unique_ptr<XLineDashItem> pItemToPut = aItem.checkForUniqueItem( & m_rDrawModel ); + + if(pItemToPut) + rOutItemSet.Put( std::move(pItemToPut) ); + else + rOutItemSet.Put(aItem); + } + break; + + case XATTR_FILLGRADIENT: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "GradientName" ) + : OUString( "FillGradientName" ); + + XFillGradientItem aItem; + aItem.PutValue( GetPropertySet()->getPropertyValue( aPropName ), MID_NAME ); + + lcl_SetContentForNamedProperty( + m_xNamedPropertyTableFactory, "com.sun.star.drawing.GradientTable" , + aItem, MID_FILLGRADIENT ); + + // translate model name to UI-name for predefined entries, so + // that the correct entry is chosen in the list of UI-names + std::unique_ptr<XFillGradientItem> pItemToPut = aItem.checkForUniqueItem( & m_rDrawModel ); + + if(pItemToPut) + rOutItemSet.Put(std::move(pItemToPut) ); + else + rOutItemSet.Put(aItem); + } + break; + + case XATTR_FILLHATCH: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "HatchName" ) + : OUString( "FillHatchName" ); + + XFillHatchItem aItem; + aItem.PutValue( GetPropertySet()->getPropertyValue( aPropName ), MID_NAME ); + + lcl_SetContentForNamedProperty( + m_xNamedPropertyTableFactory, "com.sun.star.drawing.HatchTable" , + aItem, MID_FILLHATCH ); + + // translate model name to UI-name for predefined entries, so + // that the correct entry is chosen in the list of UI-names + std::unique_ptr<XFillHatchItem> pItemToPut = aItem.checkForUniqueItem( & m_rDrawModel ); + + if(pItemToPut) + rOutItemSet.Put( std::move(pItemToPut) ); + else + rOutItemSet.Put(aItem); + } + break; + + case XATTR_FILLBITMAP: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + XFillBitmapItem aItem; + aItem.PutValue( GetPropertySet()->getPropertyValue( "FillBitmapName" ), MID_NAME ); + + lcl_SetContentForNamedProperty( + m_xNamedPropertyTableFactory, "com.sun.star.drawing.BitmapTable" , + aItem, MID_BITMAP ); + + // translate model name to UI-name for predefined entries, so + // that the correct entry is chosen in the list of UI-names + std::unique_ptr<XFillBitmapItem> pItemToPut = aItem.checkForUniqueItem( & m_rDrawModel ); + + if(pItemToPut) + rOutItemSet.Put( std::move(pItemToPut) ); + else + rOutItemSet.Put(aItem); + } + break; + + // hack, because QueryValue of XLineTransparenceItem returns sal_Int32 + // instead of sal_Int16 + case XATTR_LINETRANSPARENCE: + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "BorderTransparency" ) + : (m_GraphicObjectType == GraphicObjectType::LineDataPoint) + ? OUString( "Transparency" ) + : OUString( "LineTransparence" ); + + XLineTransparenceItem aItem; + aItem.PutValue( GetPropertySet()->getPropertyValue( aPropName ), 0 ); + + rOutItemSet.Put( aItem ); + } + break; + + // hack, because QueryValue of XFillTransparenceItem returns sal_Int32 + // instead of sal_Int16 + case XATTR_FILLTRANSPARENCE: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "Transparency" ) + : OUString( "FillTransparence" ); + + XFillTransparenceItem aItem; + aItem.PutValue( GetPropertySet()->getPropertyValue( aPropName ), 0 ); + + rOutItemSet.Put( aItem ); + } + break; + } +} + +bool GraphicPropertyItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + uno::Any aValue; + + switch( nWhichId ) + { + // bitmap property + case XATTR_FILLBMP_STRETCH: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + static const OUStringLiteral aModePropName(u"FillBitmapMode"); + bool bStretched = rItemSet.Get( XATTR_FILLBMP_STRETCH ).GetValue(); + drawing::BitmapMode aMode = + (bStretched ? drawing::BitmapMode_STRETCH : drawing::BitmapMode_NO_REPEAT); + drawing::BitmapMode aOtherMode = drawing::BitmapMode_NO_REPEAT; + + aValue <<= aMode; + GetPropertySet()->getPropertyValue( aModePropName ) >>= aOtherMode; + + // don't overwrite if it has been set to BitmapMode_REPEAT (= tiled) already + // XATTR_FILLBMP_STRETCH and XATTR_FILLBMP_TILE often come in pairs, tdf#104658 + if( aMode != aOtherMode && aOtherMode != drawing::BitmapMode_REPEAT ) + { + GetPropertySet()->setPropertyValue( aModePropName, aValue ); + bChanged = true; + } + } + break; + + case XATTR_FILLBMP_TILE: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + static const OUStringLiteral aModePropName(u"FillBitmapMode"); + bool bTiled = rItemSet.Get( XATTR_FILLBMP_TILE ).GetValue(); + drawing::BitmapMode aMode = + (bTiled ? drawing::BitmapMode_REPEAT : drawing::BitmapMode_NO_REPEAT); + + aValue <<= aMode; + if( aValue != GetPropertySet()->getPropertyValue( aModePropName )) + { + GetPropertySet()->setPropertyValue( aModePropName, aValue ); + bChanged = true; + } + } + break; + + case XATTR_FILLFLOATTRANSPARENCE: + try + { + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "TransparencyGradientName" ) + : OUString( "FillTransparenceGradientName" ); + + const XFillFloatTransparenceItem & rItem = + static_cast< const XFillFloatTransparenceItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.IsEnabled() && + rItem.QueryValue( aValue, MID_NAME )) + { + uno::Any aGradient; + rItem.QueryValue( aGradient, MID_FILLGRADIENT ); + + // add TransparencyGradient to list if it does not already exist + OUString aPreferredName; + aValue >>= aPreferredName; + aValue <<= PropertyHelper::addTransparencyGradientUniqueNameToTable( + aGradient, m_xNamedPropertyTableFactory, aPreferredName ); + + if( aValue != GetPropertySet()->getPropertyValue( aPropName )) + { + GetPropertySet()->setPropertyValue( aPropName, aValue ); + bChanged = true; + } + } + else + { + OUString aName; + if( ( GetPropertySet()->getPropertyValue( aPropName ) >>= aName ) + && !aName.isEmpty() ) + { + uno::Reference< beans::XPropertyState > xState( GetPropertySet(), uno::UNO_QUERY ); + if( xState.is()) + xState->setPropertyToDefault( aPropName ); + bChanged = true; + } + } + } + } + catch( const beans::UnknownPropertyException & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + break; + + case XATTR_GRADIENTSTEPCOUNT: + { + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "GradientStepCount" ) + : OUString( "FillGradientStepCount" ); + + sal_Int16 nStepCount = static_cast< const XGradientStepCountItem & >( + rItemSet.Get( nWhichId )).GetValue(); + + aValue <<= nStepCount; + if( aValue != GetPropertySet()->getPropertyValue( aPropName )) + { + GetPropertySet()->setPropertyValue( aPropName, aValue ); + bChanged = true; + } + } + } + break; + + case XATTR_LINEDASH: + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "BorderDashName" ) + : OUString( "LineDashName" ); + + const XLineDashItem & rItem = + static_cast< const XLineDashItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_NAME )) + { + if( aValue != GetPropertySet()->getPropertyValue( aPropName )) + { + // add LineDash to list + uno::Any aLineDash; + rItem.QueryValue( aLineDash, MID_LINEDASH ); + OUString aPreferredName; + aValue >>= aPreferredName; + aValue <<= PropertyHelper::addLineDashUniqueNameToTable( + aLineDash, m_xNamedPropertyTableFactory, aPreferredName ); + + GetPropertySet()->setPropertyValue( aPropName, aValue ); + bChanged = true; + } + } + } + break; + + case XATTR_FILLGRADIENT: + { + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "GradientName" ) + : OUString( "FillGradientName" ); + + const XFillGradientItem & rItem = + static_cast< const XFillGradientItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_NAME )) + { + if( aValue != GetPropertySet()->getPropertyValue( aPropName )) + { + // add Gradient to list + uno::Any aGradient; + rItem.QueryValue( aGradient, MID_FILLGRADIENT ); + OUString aPreferredName; + aValue >>= aPreferredName; + aValue <<= PropertyHelper::addGradientUniqueNameToTable( + aGradient, m_xNamedPropertyTableFactory, aPreferredName ); + + GetPropertySet()->setPropertyValue( aPropName, aValue ); + bChanged = true; + } + } + } + } + break; + + case XATTR_FILLHATCH: + { + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "HatchName" ) + : OUString( "FillHatchName" ); + + const XFillHatchItem & rItem = + static_cast< const XFillHatchItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_NAME )) + { + if( aValue != GetPropertySet()->getPropertyValue( aPropName )) + { + // add Hatch to list + uno::Any aHatch; + rItem.QueryValue( aHatch, MID_FILLHATCH ); + OUString aPreferredName; + aValue >>= aPreferredName; + aValue <<= PropertyHelper::addHatchUniqueNameToTable( + aHatch, m_xNamedPropertyTableFactory, aPreferredName ); + + GetPropertySet()->setPropertyValue( aPropName, aValue ); + bChanged = true; + } + } + } + } + break; + + case XATTR_FILLBITMAP: + { + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + const XFillBitmapItem & rItem = + static_cast< const XFillBitmapItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue, MID_NAME )) + { + if( aValue != GetPropertySet()->getPropertyValue( "FillBitmapName" )) + { + // add Bitmap to list + uno::Any aBitmap; + rItem.QueryValue(aBitmap, MID_BITMAP); + OUString aPreferredName; + aValue >>= aPreferredName; + aValue <<= PropertyHelper::addBitmapUniqueNameToTable( + aBitmap, m_xNamedPropertyTableFactory, aPreferredName ); + + GetPropertySet()->setPropertyValue( "FillBitmapName" , aValue ); + bChanged = true; + } + } + } + } + break; + + // hack, because QueryValue of XLineTransparenceItem returns sal_Int32 + // instead of sal_Int16 + case XATTR_LINETRANSPARENCE: + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "BorderTransparency" ) + : (m_GraphicObjectType == GraphicObjectType::LineDataPoint) + ? OUString( "Transparency" ) + : OUString( "LineTransparence" ); + + const XLineTransparenceItem & rItem = + static_cast< const XLineTransparenceItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue )) + { + OSL_ENSURE( ! aValue.isExtractableTo( + cppu::UnoType<sal_Int16>::get()), + "TransparenceItem QueryValue bug is fixed. Remove hack." ); + sal_Int32 nValue = 0; + if( aValue >>= nValue ) + { + OSL_ENSURE( nValue < SAL_MAX_INT16, "Transparency value too large" ); + sal_Int16 nValueToSet( static_cast< sal_Int16 >( nValue )); + aValue <<= nValueToSet; + + GetPropertySet()->setPropertyValue( aPropName, aValue ); + bChanged = true; + } + else + { + OSL_FAIL( "Wrong type in Transparency Any" ); + } + } + } + break; + + // hack, because QueryValue of XFillTransparenceItem returns sal_Int32 + // instead of sal_Int16 + case XATTR_FILLTRANSPARENCE: + if( lcl_supportsFillProperties( m_GraphicObjectType )) + { + OUString aPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "Transparency" ) + : OUString( "FillTransparence" ); + + const XFillTransparenceItem & rItem = + static_cast< const XFillTransparenceItem & >( + rItemSet.Get( nWhichId )); + + if( rItem.QueryValue( aValue )) + { + OSL_ENSURE( ! aValue.isExtractableTo( + cppu::UnoType<sal_Int16>::get()), + "TransparenceItem QueryValue bug is fixed. Remove hack." ); + sal_Int32 nValue = 0; + if( aValue >>= nValue ) + { + OSL_ENSURE( nValue < SAL_MAX_INT16, "Transparency value too large" ); + sal_Int16 nValueToSet( static_cast< sal_Int16 >( nValue )); + aValue <<= nValueToSet; + + GetPropertySet()->setPropertyValue( aPropName, aValue ); + // if linear or no transparence is set, delete the gradient + OUString aTransGradPropName = + (m_GraphicObjectType == GraphicObjectType::FilledDataPoint) + ? OUString( "TransparencyGradientName" ) + : OUString( "FillTransparenceGradientName" ); + GetPropertySet()->setPropertyValue( + aTransGradPropName, uno::Any( OUString() )); + + bChanged = true; + } + else + { + OSL_FAIL( "Wrong type in Transparency Any" ); + } + } + } + break; + } + + return bChanged; +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/ItemConverter.cxx b/chart2/source/controller/itemsetwrapper/ItemConverter.cxx new file mode 100644 index 000000000..d79079b77 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/ItemConverter.cxx @@ -0,0 +1,222 @@ +/* -*- 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 <ItemConverter.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <osl/diagnose.h> +#include <svl/itempool.hxx> +#include <svl/itemiter.hxx> +#include <svl/whiter.hxx> +#include <svx/svxids.hrc> +#include <tools/diagnose_ex.h> +#include <sal/log.hxx> + +using namespace ::com::sun::star; + +namespace chart::wrapper { + +ItemConverter::ItemConverter( + const uno::Reference< beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool ) : + m_xPropertySet( rPropertySet ), + m_rItemPool( rItemPool ) +{ + resetPropertySet( m_xPropertySet ); +} + +ItemConverter::~ItemConverter() +{ + stopAllComponentListening(); +} + +void ItemConverter::resetPropertySet( + const uno::Reference< beans::XPropertySet > & xPropSet ) +{ + if( !xPropSet.is()) + return; + + stopAllComponentListening(); + m_xPropertySet = xPropSet; + m_xPropertySetInfo = m_xPropertySet->getPropertySetInfo(); + + uno::Reference< lang::XComponent > xComp( m_xPropertySet, uno::UNO_QUERY ); + if( xComp.is()) + { + // method of base class ::utl::OEventListenerAdapter + startComponentListening( xComp ); + } +} + +SfxItemSet ItemConverter::CreateEmptyItemSet() const +{ + return SfxItemSet( GetItemPool(), GetWhichPairs() ); +} + +void ItemConverter::_disposing( const lang::EventObject& ) +{ +} + +void ItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + const WhichRangesContainer& pRanges = rOutItemSet.GetRanges(); + tPropertyNameWithMemberId aProperty; + SfxItemPool & rPool = GetItemPool(); + + assert(!pRanges.empty()); + OSL_ASSERT( m_xPropertySetInfo.is()); + OSL_ASSERT( m_xPropertySet.is()); + + for(const auto& rPair : pRanges) + { + sal_uInt16 nBeg = rPair.first; + sal_uInt16 nEnd = rPair.second; + + OSL_ASSERT( nBeg <= nEnd ); + for( sal_uInt16 nWhich = nBeg; nWhich <= nEnd; ++nWhich ) + { + if( GetItemProperty( nWhich, aProperty )) + { + // put the Property into the itemset + std::unique_ptr<SfxPoolItem> pItem(rPool.GetDefaultItem( nWhich ).Clone()); + + if( pItem ) + { + try + { + if( pItem->PutValue( m_xPropertySet->getPropertyValue( aProperty.first ), + aProperty.second // nMemberId + )) + { + pItem->SetWhich(nWhich); + rOutItemSet.Put( std::move(pItem) ); + } + } + catch( const beans::UnknownPropertyException & ) + { + TOOLS_WARN_EXCEPTION( "chart2", "unknown Property: " << aProperty.first); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + else + { + try + { + FillSpecialItem( nWhich, rOutItemSet ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + } +} + +void ItemConverter::FillSpecialItem( + sal_uInt16 /*nWhichId*/, SfxItemSet & /*rOutItemSet*/ ) const +{ + OSL_FAIL( "ItemConverter: Unhandled special item found!" ); +} + +bool ItemConverter::ApplySpecialItem( + sal_uInt16 /*nWhichId*/, const SfxItemSet & /*rItemSet*/ ) +{ + OSL_FAIL( "ItemConverter: Unhandled special item found!" ); + return false; +} + +bool ItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + OSL_ASSERT( m_xPropertySet.is()); + + bool bItemsChanged = false; + SfxItemIter aIter( rItemSet ); + tPropertyNameWithMemberId aProperty; + uno::Any aValue; + + for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem()) + { + if( aIter.GetItemState( false ) == SfxItemState::SET ) + { + if( GetItemProperty( pItem->Which(), aProperty )) + { + pItem->QueryValue( aValue, aProperty.second /* nMemberId */ ); + + try + { + if( aValue != m_xPropertySet->getPropertyValue( aProperty.first )) + { + m_xPropertySet->setPropertyValue( aProperty.first, aValue ); + bItemsChanged = true; + } + } + catch( const beans::UnknownPropertyException & ) + { + TOOLS_WARN_EXCEPTION( "chart2", "unknown Property: " << aProperty.first); + } + catch( const uno::Exception & ) + { + TOOLS_WARN_EXCEPTION( "chart2", "" ); + } + } + else + { + bItemsChanged = ApplySpecialItem( pItem->Which(), rItemSet ) || bItemsChanged; + } + } + } + + return bItemsChanged; +} + +void ItemConverter::InvalidateUnequalItems( SfxItemSet &rDestSet, const SfxItemSet &rSourceSet ) +{ + SfxWhichIter aIter (rSourceSet); + sal_uInt16 nWhich = aIter.FirstWhich (); + const SfxPoolItem *pPoolItem = nullptr; + + while (nWhich) + { + SfxItemState nSourceItemState = aIter.GetItemState(true, &pPoolItem); + if ((nSourceItemState == SfxItemState::SET) && + (rDestSet.GetItemState(nWhich, true, &pPoolItem) == SfxItemState::SET)) + { + if (rSourceSet.Get(nWhich) != rDestSet.Get(nWhich)) + { + if( nWhich != SID_CHAR_DLG_PREVIEW_STRING ) + { + rDestSet.InvalidateItem(nWhich); + } + } + } + else if( nSourceItemState == SfxItemState::DONTCARE ) + rDestSet.InvalidateItem(nWhich); + + nWhich = aIter.NextWhich (); + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/LegendItemConverter.cxx b/chart2/source/controller/itemsetwrapper/LegendItemConverter.cxx new file mode 100644 index 000000000..7a8dab188 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/LegendItemConverter.cxx @@ -0,0 +1,205 @@ +/* -*- 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 <LegendItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <GraphicPropertyItemConverter.hxx> +#include <CharacterPropertyItemConverter.hxx> +#include <com/sun/star/chart2/LegendPosition.hpp> +#include <com/sun/star/chart/ChartLegendExpansion.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <tools/diagnose_ex.h> + +#include <memory> + +using namespace ::com::sun::star; + +namespace chart::wrapper +{ + +LegendItemConverter::LegendItemConverter( + const css::uno::Reference< css::beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory, + const awt::Size* pRefSize ) : + ItemConverter( rPropertySet, rItemPool ) +{ + m_aConverters.emplace_back( new GraphicPropertyItemConverter( + rPropertySet, rItemPool, rDrawModel, xNamedPropertyContainerFactory, + GraphicObjectType::LineAndFillProperties )); + m_aConverters.emplace_back( new CharacterPropertyItemConverter( + rPropertySet, rItemPool, pRefSize, + "ReferencePageSize" )); +} + +LegendItemConverter::~LegendItemConverter() +{ +} + +void LegendItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + for( const auto& pConv : m_aConverters ) + pConv->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet( rOutItemSet ); +} + +bool LegendItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = false; + + for( const auto& pConv : m_aConverters ) + bResult = pConv->ApplyItemSet( rItemSet ) || bResult; + + // own items + return ItemConverter::ApplyItemSet( rItemSet ) || bResult; +} + +const WhichRangesContainer& LegendItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nLegendWhichPairs; +} + +bool LegendItemConverter::GetItemProperty( tWhichIdType /*nWhichId*/, tPropertyNameWithMemberId & /*rOutProperty*/ ) const +{ + // No own (non-special) properties + return false; +} + +bool LegendItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet& rInItemSet ) +{ + bool bChanged = false; + + switch( nWhichId ) + { + case SCHATTR_LEGEND_SHOW: + { + if( const SfxBoolItem* pShowItem = rInItemSet.GetItemIfSet( SCHATTR_LEGEND_SHOW ) ) + { + bool bShow = pShowItem->GetValue(); + bool bWasShown = true; + if( ! (GetPropertySet()->getPropertyValue( "Show" ) >>= bWasShown) || + ( bWasShown != bShow )) + { + GetPropertySet()->setPropertyValue( "Show" , uno::Any( bShow )); + bChanged = true; + } + } + + } + break; + case SCHATTR_LEGEND_POS: + { + if( const SfxInt32Item* pPosItem = rInItemSet.GetItemIfSet( SCHATTR_LEGEND_POS ) ) + { + chart2::LegendPosition eNewPos = static_cast<chart2::LegendPosition>(pPosItem->GetValue()); + + css::chart::ChartLegendExpansion eExpansion = css::chart::ChartLegendExpansion_HIGH; + switch( eNewPos ) + { + case chart2::LegendPosition_LINE_START: + case chart2::LegendPosition_LINE_END: + eExpansion = css::chart::ChartLegendExpansion_HIGH; + break; + case chart2::LegendPosition_PAGE_START: + case chart2::LegendPosition_PAGE_END: + eExpansion = css::chart::ChartLegendExpansion_WIDE; + break; + default: + break; + } + + try + { + chart2::LegendPosition eOldPos; + if( ! ( GetPropertySet()->getPropertyValue( "AnchorPosition" ) >>= eOldPos ) || + ( eOldPos != eNewPos )) + { + GetPropertySet()->setPropertyValue( "AnchorPosition" , uno::Any( eNewPos )); + GetPropertySet()->setPropertyValue( "Expansion" , uno::Any( eExpansion )); + GetPropertySet()->setPropertyValue( "RelativePosition" , uno::Any()); + bChanged = true; + } + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + } + } + break; + case SCHATTR_LEGEND_NO_OVERLAY: + { + if(const SfxBoolItem* pNoOverlayItem = rInItemSet.GetItemIfSet(SCHATTR_LEGEND_NO_OVERLAY)) + { + bool bOverlay = !pNoOverlayItem->GetValue(); + bool bOldOverlay = false; + if(!(GetPropertySet()->getPropertyValue("Overlay") >>= bOldOverlay) || + (bOldOverlay != bOverlay)) + { + GetPropertySet()->setPropertyValue("Overlay", uno::Any(bOverlay)); + bChanged = true; + } + } + + } + break; + } + + return bChanged; +} + +void LegendItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case SCHATTR_LEGEND_SHOW: + { + bool bShow = true; + GetPropertySet()->getPropertyValue( "Show" ) >>= bShow; + rOutItemSet.Put( SfxBoolItem(SCHATTR_LEGEND_SHOW, bShow) ); + } + break; + case SCHATTR_LEGEND_POS: + { + chart2::LegendPosition eLegendPos( chart2::LegendPosition_LINE_END ); + GetPropertySet()->getPropertyValue( "AnchorPosition" ) >>= eLegendPos; + rOutItemSet.Put( SfxInt32Item(SCHATTR_LEGEND_POS, static_cast<sal_Int32>(eLegendPos) ) ); + } + break; + case SCHATTR_LEGEND_NO_OVERLAY: + { + bool bOverlay = false; + GetPropertySet()->getPropertyValue("Overlay") >>= bOverlay; + rOutItemSet.Put(SfxBoolItem(SCHATTR_LEGEND_NO_OVERLAY, !bOverlay)); + } + break; + } +} + +} // namespace chart::wrapper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx b/chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx new file mode 100644 index 000000000..5f460be98 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/MultipleChartConverters.cxx @@ -0,0 +1,192 @@ +/* -*- 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 <MultipleChartConverters.hxx> + +#include "SchWhichPairs.hxx" +#include <AxisItemConverter.hxx> +#include <StatisticsItemConverter.hxx> +#include <GraphicPropertyItemConverter.hxx> +#include <DataPointItemConverter.hxx> +#include <ChartModelHelper.hxx> +#include <ChartModel.hxx> +#include <Diagram.hxx> +#include <DataSeries.hxx> +#include <TitleHelper.hxx> +#include <TitleItemConverter.hxx> +#include <Axis.hxx> +#include <AxisHelper.hxx> +#include <chartview/ExplicitValueProvider.hxx> +#include <com/sun/star/chart2/XTitle.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; + +namespace chart::wrapper { + +AllAxisItemConverter::AllAxisItemConverter( + const rtl::Reference<::chart::ChartModel> & xChartModel, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const awt::Size* pRefSize ) + : MultipleItemConverter( rItemPool ) +{ + rtl::Reference< Diagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) ); + const std::vector< rtl::Reference< Axis > > aElementList = AxisHelper::getAllAxesOfDiagram( xDiagram ); + for( rtl::Reference< Axis > const & axis : aElementList ) + { + uno::Reference< beans::XPropertySet > xObjectProperties(axis); + m_aConverters.emplace_back( new ::chart::wrapper::AxisItemConverter( + xObjectProperties, rItemPool, rDrawModel, + xChartModel, nullptr, nullptr, + pRefSize)); + } +} + +AllAxisItemConverter::~AllAxisItemConverter() +{ +} + +const WhichRangesContainer& AllAxisItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nAllAxisWhichPairs; +} + +AllGridItemConverter::AllGridItemConverter( + const rtl::Reference<::chart::ChartModel> & xChartModel, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory ) + : MultipleItemConverter( rItemPool ) +{ + rtl::Reference< Diagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) ); + const Sequence< Reference< beans::XPropertySet > > aElementList( AxisHelper::getAllGrids( xDiagram ) ); + for( Reference< beans::XPropertySet > const & xObjectProperties : aElementList ) + { + m_aConverters.emplace_back( new ::chart::wrapper::GraphicPropertyItemConverter( + xObjectProperties, rItemPool, rDrawModel, xNamedPropertyContainerFactory, + ::chart::wrapper::GraphicObjectType::LineProperties ) ); + } +} + +AllGridItemConverter::~AllGridItemConverter() +{ +} + +const WhichRangesContainer& AllGridItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nGridWhichPairs; +} + +AllDataLabelItemConverter::AllDataLabelItemConverter( + const rtl::Reference<::chart::ChartModel> & xChartModel, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory ) + : MultipleItemConverter( rItemPool ) +{ + std::vector< rtl::Reference< DataSeries > > aSeriesList = + ::chart::ChartModelHelper::getDataSeries( xChartModel ); + + for (auto const& series : aSeriesList) + { + uno::Reference< uno::XComponentContext> xContext;//do not need Context for label properties + + sal_Int32 nNumberFormat=ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel( series ); + sal_Int32 nPercentNumberFormat=ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel( + series,xChartModel); + + m_aConverters.emplace_back( + new ::chart::wrapper::DataPointItemConverter( + xChartModel, xContext, series, series, rItemPool, rDrawModel, + xNamedPropertyContainerFactory, GraphicObjectType::FilledDataPoint, + nullptr, true, false, 0, true, nNumberFormat, nPercentNumberFormat)); + } +} + +AllDataLabelItemConverter::~AllDataLabelItemConverter() +{ +} + +const WhichRangesContainer& AllDataLabelItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nDataLabelWhichPairs; +} + +AllTitleItemConverter::AllTitleItemConverter( + const rtl::Reference<::chart::ChartModel> & xChartModel, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory ) + : MultipleItemConverter( rItemPool ) +{ + for(sal_Int32 nTitle = TitleHelper::TITLE_BEGIN; nTitle < TitleHelper::NORMAL_TITLE_END; nTitle++ ) + { + uno::Reference< chart2::XTitle > xTitle( TitleHelper::getTitle( TitleHelper::eTitleType(nTitle), xChartModel ) ); + if(!xTitle.is()) + continue; + uno::Reference< beans::XPropertySet > xObjectProperties( xTitle, uno::UNO_QUERY); + m_aConverters.emplace_back( + new ::chart::wrapper::TitleItemConverter( + xObjectProperties, rItemPool, rDrawModel, xNamedPropertyContainerFactory, nullptr)); + } +} + +AllTitleItemConverter::~AllTitleItemConverter() +{ +} + +const WhichRangesContainer& AllTitleItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nTitleWhichPairs; +} + +AllSeriesStatisticsConverter::AllSeriesStatisticsConverter( + const rtl::Reference<::chart::ChartModel> & xChartModel, + SfxItemPool& rItemPool ) + : MultipleItemConverter( rItemPool ) +{ + std::vector< rtl::Reference< DataSeries > > aSeriesList = + ::chart::ChartModelHelper::getDataSeries( xChartModel ); + + for (auto const& series : aSeriesList) + { + m_aConverters.emplace_back( new ::chart::wrapper::StatisticsItemConverter( + xChartModel, series, rItemPool )); + } +} + +AllSeriesStatisticsConverter::~AllSeriesStatisticsConverter() +{} + +const WhichRangesContainer& AllSeriesStatisticsConverter::GetWhichPairs() const +{ + // must span all used items! + return nStatWhichPairs; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/MultipleItemConverter.cxx b/chart2/source/controller/itemsetwrapper/MultipleItemConverter.cxx new file mode 100644 index 000000000..5937575cc --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/MultipleItemConverter.cxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <MultipleItemConverter.hxx> + +#include <memory> + +using namespace ::com::sun::star; + +namespace chart::wrapper { + +MultipleItemConverter::MultipleItemConverter( SfxItemPool& rItemPool ) + : ItemConverter( nullptr, rItemPool ) +{ +} +MultipleItemConverter::~MultipleItemConverter() +{ +} + +void MultipleItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + auto aIter = m_aConverters.begin(); + auto aEnd = m_aConverters.end(); + if( aIter != aEnd ) + { + (*aIter)->FillItemSet( rOutItemSet ); + ++aIter; + } + for( ; aIter != aEnd; ++aIter ) + { + SfxItemSet aSet = CreateEmptyItemSet(); + (*aIter)->FillItemSet( aSet ); + InvalidateUnequalItems( rOutItemSet, aSet ); + } + // no own items +} + +bool MultipleItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = false; + + for( const auto& pConv : m_aConverters ) + bResult = pConv->ApplyItemSet( rItemSet ) || bResult; + + // no own items + return bResult; +} + +bool MultipleItemConverter::GetItemProperty( tWhichIdType /*nWhichId*/, tPropertyNameWithMemberId & /*rOutProperty*/ ) const +{ + return false; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/RegressionCurveItemConverter.cxx b/chart2/source/controller/itemsetwrapper/RegressionCurveItemConverter.cxx new file mode 100644 index 000000000..5683b468c --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/RegressionCurveItemConverter.cxx @@ -0,0 +1,350 @@ +/* -*- 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 <RegressionCurveHelper.hxx> +#include <RegressionCurveModel.hxx> +#include <RegressionCurveItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <GraphicPropertyItemConverter.hxx> +#include <DataSeries.hxx> + +#include <com/sun/star/chart2/XRegressionCurve.hpp> +#include <osl/diagnose.h> + +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <svl/stritem.hxx> + +using namespace ::com::sun::star; + +namespace +{ +template <class T, class D> +bool lclConvertToPropertySet(const SfxItemSet& rItemSet, sal_uInt16 nWhichId, const uno::Reference<beans::XPropertySet>& xProperties, const OUString& aPropertyID) +{ + OSL_ASSERT(xProperties.is()); + if( xProperties.is() ) + { + T aValue = static_cast<T>(static_cast<const D&>(rItemSet.Get( nWhichId )).GetValue()); + T aOldValue = aValue; + bool aSuccess = xProperties->getPropertyValue( aPropertyID ) >>= aOldValue; + if (!aSuccess || aOldValue != aValue) + { + xProperties->setPropertyValue( aPropertyID , uno::Any( aValue )); + return true; + } + } + return false; +} + +template <class T, class D> +void lclConvertToItemSet(SfxItemSet& rItemSet, sal_uInt16 nWhichId, const uno::Reference<beans::XPropertySet>& xProperties, const OUString& aPropertyID) +{ + OSL_ASSERT(xProperties.is()); + if( xProperties.is() ) + { + T aValue = static_cast<T>(static_cast<const D&>(rItemSet.Get( nWhichId )).GetValue()); + if(xProperties->getPropertyValue( aPropertyID ) >>= aValue) + { + rItemSet.Put(D( nWhichId, aValue )); + } + } +} + +void lclConvertToItemSetDouble(SfxItemSet& rItemSet, TypedWhichId<SvxDoubleItem> nWhichId, const uno::Reference<beans::XPropertySet>& xProperties, const OUString& aPropertyID) +{ + OSL_ASSERT(xProperties.is()); + if( xProperties.is() ) + { + double aValue = rItemSet.Get( nWhichId ).GetValue(); + if(xProperties->getPropertyValue( aPropertyID ) >>= aValue) + { + rItemSet.Put(SvxDoubleItem( aValue, nWhichId )); + } + } +} + +} // anonymous namespace + +namespace chart::wrapper +{ + +RegressionCurveItemConverter::RegressionCurveItemConverter( + const uno::Reference< beans::XPropertySet >& rPropertySet, + const rtl::Reference< DataSeries >& xContainer, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory ) : + ItemConverter( rPropertySet, rItemPool ), + m_spGraphicConverter( std::make_shared<GraphicPropertyItemConverter>( + rPropertySet, rItemPool, rDrawModel, + xNamedPropertyContainerFactory, + GraphicObjectType::LineProperties )), + m_xCurveContainer( xContainer ) +{} + +RegressionCurveItemConverter::~RegressionCurveItemConverter() +{} + +void RegressionCurveItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + m_spGraphicConverter->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet( rOutItemSet ); +} + +bool RegressionCurveItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = m_spGraphicConverter->ApplyItemSet( rItemSet ); + + // own items + return ItemConverter::ApplyItemSet( rItemSet ) || bResult; +} + +const WhichRangesContainer& RegressionCurveItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nRegressionCurveWhichPairs; +} + +bool RegressionCurveItemConverter::GetItemProperty( + tWhichIdType /* nWhichId */, tPropertyNameWithMemberId & /* rOutProperty */ ) const +{ + // No own (non-special) properties + return false; +} + +bool RegressionCurveItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + uno::Reference< chart2::XRegressionCurve > xCurve( GetPropertySet(), uno::UNO_QUERY ); + bool bChanged = false; + + OSL_ASSERT(xCurve.is()); + if(!xCurve.is()) + return false; + + switch( nWhichId ) + { + case SCHATTR_REGRESSION_TYPE: + { + SvxChartRegress eRegress = RegressionCurveHelper::getRegressionType(xCurve); + SvxChartRegress eNewRegress = static_cast< const SvxChartRegressItem & >( + rItemSet.Get( nWhichId )).GetValue(); + if( eRegress != eNewRegress ) + { + // note that changing the regression type changes the object + // for which this converter was created. Not optimal, but + // currently the only way to handle the type in the + // regression curve properties dialog + xCurve = RegressionCurveHelper::changeRegressionCurveType( + eNewRegress, + m_xCurveContainer, + xCurve); + uno::Reference<beans::XPropertySet> xProperties( xCurve, uno::UNO_QUERY ); + resetPropertySet( xProperties ); + bChanged = true; + } + } + break; + + case SCHATTR_REGRESSION_DEGREE: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<sal_Int32, SfxInt32Item>(rItemSet, nWhichId, xProperties, "PolynomialDegree"); + } + break; + + case SCHATTR_REGRESSION_PERIOD: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<sal_Int32, SfxInt32Item>(rItemSet, nWhichId, xProperties, "MovingAveragePeriod"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<double, SvxDoubleItem>(rItemSet, nWhichId, xProperties, "ExtrapolateForward"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<double, SvxDoubleItem>(rItemSet, nWhichId, xProperties, "ExtrapolateBackward"); + } + break; + + case SCHATTR_REGRESSION_SET_INTERCEPT: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<bool, SfxBoolItem>(rItemSet, nWhichId, xProperties, "ForceIntercept"); + } + break; + + case SCHATTR_REGRESSION_INTERCEPT_VALUE: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<double, SvxDoubleItem>(rItemSet, nWhichId, xProperties, "InterceptValue"); + } + break; + + case SCHATTR_REGRESSION_CURVE_NAME: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<OUString, SfxStringItem>(rItemSet, nWhichId, xProperties, "CurveName"); + } + break; + + case SCHATTR_REGRESSION_MOVING_TYPE: + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + bChanged = lclConvertToPropertySet<sal_Int32, SfxInt32Item>(rItemSet, nWhichId, xProperties, "MovingAverageType"); + } + break; + + case SCHATTR_REGRESSION_SHOW_EQUATION: + { + uno::Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); + bChanged = lclConvertToPropertySet<bool, SfxBoolItem>(rItemSet, nWhichId, xEqProp, "ShowEquation"); + } + break; + + case SCHATTR_REGRESSION_XNAME: + { + uno::Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); + bChanged = lclConvertToPropertySet<OUString, SfxStringItem>(rItemSet, nWhichId, xEqProp, "XName"); + } + break; + + case SCHATTR_REGRESSION_YNAME: + { + uno::Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); + bChanged = lclConvertToPropertySet<OUString, SfxStringItem>(rItemSet, nWhichId, xEqProp, "YName"); + } + break; + + case SCHATTR_REGRESSION_SHOW_COEFF: + { + uno::Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); + bChanged = lclConvertToPropertySet<bool, SfxBoolItem>(rItemSet, nWhichId, xEqProp, "ShowCorrelationCoefficient"); + } + break; + + } + return bChanged; +} + +void RegressionCurveItemConverter::FillSpecialItem(sal_uInt16 nWhichId, SfxItemSet& rOutItemSet ) const +{ + uno::Reference<chart2::XRegressionCurve> xCurve(GetPropertySet(), uno::UNO_QUERY); + OSL_ASSERT(xCurve.is()); + if(!xCurve.is()) + return; + + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + + switch( nWhichId ) + { + case SCHATTR_REGRESSION_TYPE: + { + SvxChartRegress eRegress = RegressionCurveHelper::getRegressionType(xCurve); + rOutItemSet.Put( SvxChartRegressItem( eRegress, SCHATTR_REGRESSION_TYPE )); + } + break; + + case SCHATTR_REGRESSION_DEGREE: + { + lclConvertToItemSet<sal_Int32, SfxInt32Item>(rOutItemSet, nWhichId, xProperties, "PolynomialDegree"); + } + break; + + case SCHATTR_REGRESSION_PERIOD: + { + lclConvertToItemSet<sal_Int32, SfxInt32Item>(rOutItemSet, nWhichId, xProperties, "MovingAveragePeriod"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD: + { + lclConvertToItemSetDouble(rOutItemSet, SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD, xProperties, "ExtrapolateForward"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD: + { + lclConvertToItemSetDouble(rOutItemSet, SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD, xProperties, "ExtrapolateBackward"); + } + break; + + case SCHATTR_REGRESSION_SET_INTERCEPT: + { + lclConvertToItemSet<bool, SfxBoolItem>(rOutItemSet, nWhichId, xProperties, "ForceIntercept"); + } + break; + + case SCHATTR_REGRESSION_INTERCEPT_VALUE: + { + lclConvertToItemSetDouble(rOutItemSet, SCHATTR_REGRESSION_INTERCEPT_VALUE, xProperties, "InterceptValue"); + } + break; + + case SCHATTR_REGRESSION_CURVE_NAME: + { + lclConvertToItemSet<OUString, SfxStringItem>(rOutItemSet, nWhichId, xProperties, "CurveName"); + } + break; + + case SCHATTR_REGRESSION_MOVING_TYPE: + { + lclConvertToItemSet<sal_Int32, SfxInt32Item>(rOutItemSet, nWhichId, xProperties, "MovingAverageType"); + } + break; + + case SCHATTR_REGRESSION_SHOW_EQUATION: + { + lclConvertToItemSet<bool, SfxBoolItem>(rOutItemSet, nWhichId, xCurve->getEquationProperties(), "ShowEquation"); + } + break; + + case SCHATTR_REGRESSION_XNAME: + { + lclConvertToItemSet<OUString, SfxStringItem>(rOutItemSet, nWhichId, xCurve->getEquationProperties(), "XName"); + } + break; + + case SCHATTR_REGRESSION_YNAME: + { + lclConvertToItemSet<OUString, SfxStringItem>(rOutItemSet, nWhichId, xCurve->getEquationProperties(), "YName"); + } + break; + + case SCHATTR_REGRESSION_SHOW_COEFF: + { + lclConvertToItemSet<bool, SfxBoolItem>(rOutItemSet, nWhichId, xCurve->getEquationProperties(), "ShowCorrelationCoefficient"); + } + break; + } +} + +} // namespace chart::wrapper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/RegressionEquationItemConverter.cxx b/chart2/source/controller/itemsetwrapper/RegressionEquationItemConverter.cxx new file mode 100644 index 000000000..22fc379b2 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/RegressionEquationItemConverter.cxx @@ -0,0 +1,149 @@ +/* -*- 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 <RegressionEquationItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <ItemPropertyMap.hxx> +#include <GraphicPropertyItemConverter.hxx> +#include <CharacterPropertyItemConverter.hxx> +#include <unonames.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <svl/intitem.hxx> + +#include <memory> + +using namespace ::com::sun::star; + +namespace chart::wrapper { + +namespace { + +ItemPropertyMapType & lcl_GetEquationPropertyMap() +{ + static ItemPropertyMapType aEquationPropertyMap; + + return aEquationPropertyMap; +}; + +} // anonymous namespace + +RegressionEquationItemConverter::RegressionEquationItemConverter( + const css::uno::Reference< css::beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory, + const awt::Size* pRefSize ) : + ItemConverter( rPropertySet, rItemPool ) +{ + m_aConverters.emplace_back( new GraphicPropertyItemConverter( + rPropertySet, rItemPool, rDrawModel, + xNamedPropertyContainerFactory, + GraphicObjectType::LineAndFillProperties )); + + m_aConverters.emplace_back( + new CharacterPropertyItemConverter(rPropertySet, rItemPool, pRefSize, "ReferencePageSize")); +} + +RegressionEquationItemConverter::~RegressionEquationItemConverter() +{ +} + +void RegressionEquationItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + for( const auto& pConv : m_aConverters ) + pConv->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet( rOutItemSet ); +} + +bool RegressionEquationItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = false; + + for( const auto& pConv : m_aConverters ) + bResult = pConv->ApplyItemSet( rItemSet ); + + // own items + return ItemConverter::ApplyItemSet( rItemSet ) || bResult; +} + +const WhichRangesContainer& RegressionEquationItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nRegEquationWhichPairs; +} + +bool RegressionEquationItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const +{ + ItemPropertyMapType & rMap( lcl_GetEquationPropertyMap()); + ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId )); + + if( aIt == rMap.end()) + return false; + + rOutProperty =(*aIt).second; + return true; +} + +bool RegressionEquationItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + + switch( nWhichId ) + { + case SID_ATTR_NUMBERFORMAT_VALUE: + { + uno::Any aValue( static_cast< sal_Int32 >( + static_cast< const SfxUInt32Item & >( + rItemSet.Get( nWhichId )).GetValue())); + if (GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT) != aValue) + { + GetPropertySet()->setPropertyValue(CHART_UNONAME_NUMFMT, aValue); + bChanged = true; + } + } + break; + } + + return bChanged; +} + +void RegressionEquationItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case SID_ATTR_NUMBERFORMAT_VALUE: + { + sal_Int32 nFormatKey = 0; + if (GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nFormatKey) + { + rOutItemSet.Put( SfxUInt32Item( nWhichId, nFormatKey )); + } + } + break; + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx b/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx new file mode 100644 index 000000000..3c1387009 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx @@ -0,0 +1,174 @@ +/* -*- 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 <svl/whichranges.hxx> +#include <svx/svxids.hrc> +#include <svx/xdef.hxx> +#include <svx/svddef.hxx> +#include <editeng/eeitem.hxx> + +#include <chartview/ChartSfxItemIds.hxx> + +const WhichRangesContainer nTitleWhichPairs(svl::Items< + SCHATTR_TEXT_START, SCHATTR_TEXT_END, + XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx + XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1018 - 1046 svx/xdef.hxx + SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST, // 1067 - 1078 svx/svddef.hxx + EE_ITEMS_START, EE_ITEMS_END, // Characters + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING // Characters +>); + +const WhichRangesContainer nAxisWhichPairs(svl::Items< + SCHATTR_TEXT_START, SCHATTR_TEXT_END, + SCHATTR_AXIS_START, SCHATTR_AXIS_END, + XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx + EE_ITEMS_START, EE_ITEMS_END, // Characters + SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE, // 10585 - 10585 svx/svxids.hrc + SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE, // 11432 svx/svxids.hrc + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING // Characters +>); + +const WhichRangesContainer nAllAxisWhichPairs(svl::Items< + SCHATTR_TEXT_START, SCHATTR_TEXT_END, + SCHATTR_AXIS_LABEL_START, SCHATTR_AXIS_LABEL_END, + XATTR_LINE_FIRST, XATTR_LINE_LAST, + EE_ITEMS_START, EE_ITEMS_END, // Characters + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING // Characters +>); + +const WhichRangesContainer nGridWhichPairs(svl::Items< + XATTR_LINE_FIRST, XATTR_LINE_LAST // 1000 - 1016 svx/xdef.hxx +>); + +const WhichRangesContainer nLegendWhichPairs(svl::Items< + SCHATTR_LEGEND_START, SCHATTR_LEGEND_END, // 3 - 3 sch/schattr.hxx + XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx + XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1018 - 1046 svx/xdef.hxx + SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST, // 1067 - 1078 svx/svddef.hxx + EE_ITEMS_START, EE_ITEMS_END, // Characters + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING // Characters +>); + +const WhichRangesContainer nDataLabelWhichPairs(svl::Items< + SCHATTR_DATADESCR_START, SCHATTR_DATADESCR_END, + SCHATTR_TEXT_DEGREES,SCHATTR_TEXT_DEGREES, + EE_PARA_WRITINGDIR,EE_PARA_WRITINGDIR, + SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, /* 10585 - 10585 svx/svxids.hrc */ + SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE /* 11432 svx/svxids.hrc */ +>); + +const WhichRangesContainer nDataPointWhichPairs(svl::Items< + SCHATTR_DATADESCR_START, SCHATTR_DATADESCR_END, /* 1 - 2 sch/schattr.hxx*/ + SCHATTR_TEXT_DEGREES, SCHATTR_TEXT_DEGREES, + SCHATTR_STYLE_START,SCHATTR_STYLE_END, /* 59 - 68 sch/schattr.hxx*/ + SCHATTR_SYMBOL_BRUSH,SCHATTR_SYMBOL_BRUSH, /* 94 sch/schattr.hxx*/ + SCHATTR_SYMBOL_SIZE,SCHATTR_SYMBOL_SIZE, /* 97 sch/schattr.hxx*/ + SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY, SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY, + XATTR_LINE_FIRST, XATTR_LINE_LAST, /* 1000 - 1016 svx/xdef.hxx */ + XATTR_FILL_FIRST, XATTR_FILL_LAST, /* 1018 - 1046 svx/xdef.hxx */ + SDRATTR_3D_FIRST, SDRATTR_3D_LAST, /* 1244 - 1334 svx/svddef.hxx */ + EE_ITEMS_START, EE_ITEMS_END, /* 3994 - 4037 editeng/eeitem.hxx */ + SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, /* 10585 - 10585 svx/svxids.hrc */ + SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE, /* 11432 svx/svxids.hrc */ + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING +>); + +const WhichRangesContainer nTextLabelWhichPairs(svl::Items< + SCHATTR_DATADESCR_START, SCHATTR_DATADESCR_END, + SCHATTR_TEXT_DEGREES, SCHATTR_TEXT_DEGREES, + SCHATTR_STYLE_SYMBOL, SCHATTR_STYLE_SYMBOL, + SCHATTR_SYMBOL_BRUSH, SCHATTR_SYMBOL_BRUSH, + SCHATTR_SYMBOL_SIZE, SCHATTR_SYMBOL_SIZE, + XATTR_LINESTYLE, XATTR_LINECOLOR, + XATTR_LINETRANSPARENCE, XATTR_LINETRANSPARENCE, + EE_ITEMS_START, EE_ITEMS_END, + SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, + SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE, + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING +>); + +const WhichRangesContainer nSeriesOptionsWhichPairs(svl::Items< + SCHATTR_AXIS,SCHATTR_AXIS, /* 69 sch/schattr.hxx*/ + SCHATTR_BAR_OVERLAP,SCHATTR_BAR_CONNECT, /* 98 - 100 (incl. SCHATTR_GAPWIDTH) */ + SCHATTR_GROUP_BARS_PER_AXIS,SCHATTR_AXIS_FOR_ALL_SERIES +>); + +// nDataPointWhichPairs + nSeriesOptionsWhichPairs +const WhichRangesContainer nRowWhichPairs(svl::Items< + SCHATTR_DATADESCR_START, SCHATTR_DATADESCR_END, /* 1 - 2 sch/schattr.hxx*/ + SCHATTR_TEXT_DEGREES, SCHATTR_TEXT_DEGREES, + SCHATTR_STYLE_START,SCHATTR_STYLE_END, /* 59 - 68 sch/schattr.hxx*/ + SCHATTR_AXIS,SCHATTR_AXIS, /* 69 sch/schattr.hxx*/ + SCHATTR_SYMBOL_BRUSH,SCHATTR_SYMBOL_BRUSH, /* 94 sch/schattr.hxx*/ + SCHATTR_SYMBOL_SIZE,SCHATTR_SYMBOL_SIZE, /* 97 sch/schattr.hxx*/ + SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY, SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY, + SCHATTR_BAR_OVERLAP,SCHATTR_BAR_CONNECT, /* 98 - 100 (incl. SCHATTR_GAPWIDTH) */ + SCHATTR_GROUP_BARS_PER_AXIS,SCHATTR_AXIS_FOR_ALL_SERIES, + XATTR_LINE_FIRST, XATTR_LINE_LAST, /* 1000 - 1016 svx/xdef.hxx */ + XATTR_FILL_FIRST, XATTR_FILL_LAST, /* 1018 - 1046 svx/xdef.hxx */ + SDRATTR_3D_FIRST, SDRATTR_3D_LAST, /* 1244 - 1334 svx/svddef.hxx */ + EE_ITEMS_START, EE_ITEMS_END, /* 3994 - 4037 editeng/eeitem.hxx */ + SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, /* 10585 - 10585 svx/svxids.hrc */ + SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE, /* 11432 svx/svxids.hrc */ + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING +>); + +const WhichRangesContainer nStatWhichPairs(svl::Items< + SCHATTR_STAT_START, SCHATTR_STAT_END, // 45 - 52 sch/schattr.hxx + SCHATTR_REGRESSION_START, SCHATTR_REGRESSION_END // 108 - 109 +>); + +const WhichRangesContainer nErrorBarWhichPairs(svl::Items< + SCHATTR_STAT_START, SCHATTR_STAT_END, // 45 - 52 sch/schattr.hxx + XATTR_LINE_FIRST, XATTR_LINE_LAST // 1000 - 1016 svx/xdef.hxx +>); + +// for CharacterProperties + +const WhichRangesContainer nCharacterPropertyWhichPairs(svl::Items< + EE_ITEMS_START, EE_ITEMS_END, // Characters + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING // Characters +>); + +const WhichRangesContainer nLinePropertyWhichPairs(svl::Items< + XATTR_LINE_FIRST, XATTR_LINE_LAST // 1000 - 1016 svx/xdef.hxx +>); + +const WhichRangesContainer nLineAndFillPropertyWhichPairs(svl::Items< + XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx + XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1000 - 1016 svx/xdef.hxx + SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST // 1067 - 1078 svx/svddef.hxx +>); + +const WhichRangesContainer nRegressionCurveWhichPairs(svl::Items< + SCHATTR_REGRESSION_START, SCHATTR_REGRESSION_END, // 108 - 109 + XATTR_LINE_FIRST, XATTR_LINE_LAST // 1000 - 1016 svx/xdef.hxx +>); + +const WhichRangesContainer nRegEquationWhichPairs(svl::Items< + XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx + XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1018 - 1046 svx/xdef.hxx + SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST, // 1067 - 1078 svx/svddef.hxx + EE_ITEMS_START, EE_ITEMS_END, // Characters + SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE, // 10585 - 10585 svx/svxids.hrc + SID_CHAR_DLG_PREVIEW_STRING, SID_CHAR_DLG_PREVIEW_STRING // Characters +>); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/SeriesOptionsItemConverter.cxx b/chart2/source/controller/itemsetwrapper/SeriesOptionsItemConverter.cxx new file mode 100644 index 000000000..2f84084a1 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/SeriesOptionsItemConverter.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 <SeriesOptionsItemConverter.hxx> +#include "SchWhichPairs.hxx" + +#include <ChartModelHelper.hxx> +#include <ChartType.hxx> +#include <Axis.hxx> +#include <AxisHelper.hxx> +#include <DiagramHelper.hxx> +#include <Diagram.hxx> +#include <ChartTypeHelper.hxx> +#include <DataSeriesHelper.hxx> +#include <ChartModel.hxx> +#include <BaseCoordinateSystem.hxx> + +#include <com/sun/star/chart2/XDataSeries.hpp> + +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <svl/ilstitem.hxx> +#include <svx/sdangitm.hxx> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; + +namespace chart::wrapper +{ + +SeriesOptionsItemConverter::SeriesOptionsItemConverter( + const rtl::Reference<::chart::ChartModel>& xChartModel + , const uno::Reference< uno::XComponentContext > & xContext + , const uno::Reference< beans::XPropertySet >& xPropertySet + , SfxItemPool& rItemPool ) + : ItemConverter( xPropertySet, rItemPool ) + , m_xChartModel(xChartModel) + , m_xCC(xContext) + , m_bAttachToMainAxis(true) + , m_bSupportingOverlapAndGapWidthProperties(false) + , m_bSupportingBarConnectors(false) + , m_nBarOverlap(0) + , m_nGapWidth(100) + , m_bConnectBars(false) + , m_bSupportingAxisSideBySide(false) + , m_bGroupBarsPerAxis(true) + , m_bSupportingStartingAngle(false) + , m_nStartingAngle(90) + , m_bClockwise(false) + , m_nMissingValueTreatment(0) + , m_bSupportingPlottingOfHiddenCells(false) + , m_bIncludeHiddenCells(true) + , m_bHideLegendEntry(false) +{ + try + { + uno::Reference< XDataSeries > xDataSeries( xPropertySet, uno::UNO_QUERY ); + + m_bAttachToMainAxis = DiagramHelper::isSeriesAttachedToMainAxis( xDataSeries ); + + rtl::Reference< Diagram > xDiagram( ChartModelHelper::findDiagram(xChartModel) ); + rtl::Reference< ChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram , xDataSeries ) ); + + m_xCooSys = DataSeriesHelper::getCoordinateSystemOfSeries( xDataSeries, xDiagram ); + if( m_xCooSys.is() ) + { + rtl::Reference< Axis > xAxis = AxisHelper::getAxis( 1, 0, m_xCooSys ); + chart2::ScaleData aScale( xAxis->getScaleData() ); + m_bClockwise = (aScale.Orientation == chart2::AxisOrientation_REVERSE); + } + + sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram ); + m_bSupportingOverlapAndGapWidthProperties = ChartTypeHelper::isSupportingOverlapAndGapWidthProperties( xChartType, nDimensionCount ); + + if( m_bSupportingOverlapAndGapWidthProperties ) + { + + sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries); + + uno::Sequence< sal_Int32 > aBarPositionSequence; + if( xChartType.is() ) + { + if( xChartType->getPropertyValue( "OverlapSequence" ) >>= aBarPositionSequence ) + { + if( nAxisIndex >= 0 && nAxisIndex < aBarPositionSequence.getLength() ) + m_nBarOverlap = aBarPositionSequence[nAxisIndex]; + } + if( xChartType->getPropertyValue( "GapwidthSequence" ) >>= aBarPositionSequence ) + { + if( nAxisIndex >= 0 && nAxisIndex < aBarPositionSequence.getLength() ) + m_nGapWidth = aBarPositionSequence[nAxisIndex]; + } + } + } + + m_bSupportingBarConnectors = ChartTypeHelper::isSupportingBarConnectors( xChartType, nDimensionCount ); + if( m_bSupportingBarConnectors && xDiagram.is() ) + { + xDiagram->getPropertyValue( "ConnectBars" ) >>= m_bConnectBars; + } + + m_bSupportingAxisSideBySide = ChartTypeHelper::isSupportingAxisSideBySide( xChartType, nDimensionCount ); + if( m_bSupportingAxisSideBySide && xDiagram.is() ) + { + xDiagram->getPropertyValue( "GroupBarsPerAxis" ) >>= m_bGroupBarsPerAxis; + } + + m_bSupportingStartingAngle = ChartTypeHelper::isSupportingStartingAngle( xChartType ); + if( m_bSupportingStartingAngle ) + { + xDiagram->getPropertyValue( "StartingAngle" ) >>= m_nStartingAngle; + } + + m_aSupportedMissingValueTreatments = ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ); + m_nMissingValueTreatment = DiagramHelper::getCorrectedMissingValueTreatment( + ChartModelHelper::findDiagram(m_xChartModel), xChartType ); + + uno::Reference< beans::XPropertySet > xProp( m_xChartModel->getDataProvider(), uno::UNO_QUERY ); + if( xProp.is() ) + { + try + { + //test whether the data provider offers this property + xProp->getPropertyValue( "IncludeHiddenCells" ); + //if not exception is thrown the property is offered + m_bSupportingPlottingOfHiddenCells = true; + xDiagram->getPropertyValue( "IncludeHiddenCells" ) >>= m_bIncludeHiddenCells; + } + catch( const beans::UnknownPropertyException& ) + { + } + } + + m_bHideLegendEntry = !xPropertySet->getPropertyValue("ShowLegendEntry").get<bool>(); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +SeriesOptionsItemConverter::~SeriesOptionsItemConverter() +{ +} + +const WhichRangesContainer& SeriesOptionsItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nSeriesOptionsWhichPairs; +} + +bool SeriesOptionsItemConverter::GetItemProperty( tWhichIdType /*nWhichId*/, tPropertyNameWithMemberId & /*rOutProperty*/ ) const +{ + return false; +} + +bool SeriesOptionsItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + switch( nWhichId ) + { + case SCHATTR_AXIS: + { + sal_Int32 nItemValue = static_cast< const SfxInt32Item & >( + rItemSet.Get( nWhichId )).GetValue(); + bool bAttachToMainAxis = nItemValue == CHART_AXIS_PRIMARY_Y; + if( bAttachToMainAxis != m_bAttachToMainAxis ) + { + //change model: + bChanged = DiagramHelper::attachSeriesToAxis( bAttachToMainAxis, uno::Reference< XDataSeries >::query( GetPropertySet() ) + , ChartModelHelper::findDiagram(m_xChartModel), m_xCC ); + + if( bChanged ) + m_bAttachToMainAxis = bAttachToMainAxis; + } + } + break; + + case SCHATTR_BAR_OVERLAP: + case SCHATTR_BAR_GAPWIDTH: + { + if( m_bSupportingOverlapAndGapWidthProperties ) + { + sal_Int32& rBarPosition = ( nWhichId == SCHATTR_BAR_OVERLAP ) ? m_nBarOverlap : m_nGapWidth; + rBarPosition = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue(); + + OUString aPropName("GapwidthSequence" ); + if( nWhichId == SCHATTR_BAR_OVERLAP ) + aPropName = "OverlapSequence"; + + uno::Reference< XDataSeries > xDataSeries( GetPropertySet(), uno::UNO_QUERY ); + rtl::Reference< Diagram > xDiagram( ChartModelHelper::findDiagram(m_xChartModel) ); + rtl::Reference< ChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram , xDataSeries ) ); + if( xChartType.is() ) + { + sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries); + uno::Sequence< sal_Int32 > aBarPositionSequence; + if( xChartType->getPropertyValue( aPropName ) >>= aBarPositionSequence ) + { + bool bGroupBarsPerAxis = rItemSet.Get( SCHATTR_GROUP_BARS_PER_AXIS ).GetValue(); + if(!bGroupBarsPerAxis) + { + //set the same value for all axes + for( auto & pos : asNonConstRange(aBarPositionSequence) ) + pos = rBarPosition; + } + else if( nAxisIndex >= 0 && nAxisIndex < aBarPositionSequence.getLength() ) + aBarPositionSequence.getArray()[nAxisIndex] = rBarPosition; + + xChartType->setPropertyValue( aPropName, uno::Any(aBarPositionSequence) ); + bChanged = true; + } + } + } + } + break; + + case SCHATTR_BAR_CONNECT: + { + m_bConnectBars = static_cast< const SfxBoolItem & >( + rItemSet.Get( nWhichId )).GetValue(); + if( m_bSupportingBarConnectors ) + { + bool bOldConnectBars = false; + rtl::Reference< Diagram > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); + if( xDiagramProperties.is() && + (xDiagramProperties->getPropertyValue( "ConnectBars" ) >>= bOldConnectBars) && + bOldConnectBars != m_bConnectBars ) + { + xDiagramProperties->setPropertyValue( "ConnectBars" , uno::Any(m_bConnectBars) ); + bChanged = true; + } + } + } + break; + + case SCHATTR_GROUP_BARS_PER_AXIS: + { + m_bGroupBarsPerAxis = static_cast< const SfxBoolItem & >( + rItemSet.Get( nWhichId )).GetValue(); + if( m_bSupportingAxisSideBySide ) + { + bool bOldGroupBarsPerAxis = true; + rtl::Reference< Diagram > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); + if( xDiagramProperties.is() && + (xDiagramProperties->getPropertyValue( "GroupBarsPerAxis" ) >>= bOldGroupBarsPerAxis) && + bOldGroupBarsPerAxis != m_bGroupBarsPerAxis ) + { + xDiagramProperties->setPropertyValue( "GroupBarsPerAxis" , uno::Any(m_bGroupBarsPerAxis) ); + bChanged = true; + } + } + } + break; + + case SCHATTR_STARTING_ANGLE: + { + if( m_bSupportingStartingAngle ) + { + m_nStartingAngle = static_cast< const SdrAngleItem & >( rItemSet.Get( nWhichId )).GetValue().get() / 100; + rtl::Reference< Diagram > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); + if( xDiagramProperties.is() ) + { + xDiagramProperties->setPropertyValue( "StartingAngle" , uno::Any(m_nStartingAngle) ); + bChanged = true; + } + } + } + break; + + case SCHATTR_CLOCKWISE: + { + bool bClockwise = static_cast< const SfxBoolItem & >( + rItemSet.Get( nWhichId )).GetValue(); + if( m_xCooSys.is() ) + { + rtl::Reference< Axis > xAxis = AxisHelper::getAxis( 1, 0, m_xCooSys ); + if( xAxis.is() ) + { + chart2::ScaleData aScaleData( xAxis->getScaleData() ); + aScaleData.Orientation = bClockwise ? chart2::AxisOrientation_REVERSE : chart2::AxisOrientation_MATHEMATICAL; + xAxis->setScaleData( aScaleData ); + bChanged = true; + } + } + } + break; + + case SCHATTR_MISSING_VALUE_TREATMENT: + { + if( m_aSupportedMissingValueTreatments.hasElements() ) + { + sal_Int32 nNew = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue(); + if( m_nMissingValueTreatment != nNew ) + { + try + { + rtl::Reference< Diagram > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); + if( xDiagramProperties.is() ) + { + xDiagramProperties->setPropertyValue( "MissingValueTreatment" , uno::Any( nNew )); + bChanged = true; + } + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + } + } + break; + case SCHATTR_INCLUDE_HIDDEN_CELLS: + { + if( m_bSupportingPlottingOfHiddenCells ) + { + bool bIncludeHiddenCells = static_cast<const SfxBoolItem &>(rItemSet.Get(nWhichId)).GetValue(); + if (bIncludeHiddenCells != m_bIncludeHiddenCells) + { + if (m_xChartModel) + bChanged = ChartModelHelper::setIncludeHiddenCells( bIncludeHiddenCells, *m_xChartModel ); + } + } + } + break; + case SCHATTR_HIDE_LEGEND_ENTRY: + { + bool bHideLegendEntry = static_cast<const SfxBoolItem &>(rItemSet.Get(nWhichId)).GetValue(); + if (bHideLegendEntry != m_bHideLegendEntry) + { + GetPropertySet()->setPropertyValue("ShowLegendEntry", css::uno::Any(!bHideLegendEntry)); + } + } + break; + } + return bChanged; +} + +void SeriesOptionsItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case SCHATTR_AXIS: + { + sal_Int32 nItemValue = m_bAttachToMainAxis ? CHART_AXIS_PRIMARY_Y : CHART_AXIS_SECONDARY_Y; + rOutItemSet.Put( SfxInt32Item(nWhichId,nItemValue ) ); + break; + } + case SCHATTR_BAR_OVERLAP: + { + if( m_bSupportingOverlapAndGapWidthProperties ) + rOutItemSet.Put( SfxInt32Item(nWhichId,m_nBarOverlap) ); + break; + } + case SCHATTR_BAR_GAPWIDTH: + { + if( m_bSupportingOverlapAndGapWidthProperties ) + rOutItemSet.Put( SfxInt32Item(nWhichId,m_nGapWidth) ); + break; + } + case SCHATTR_BAR_CONNECT: + { + if( m_bSupportingBarConnectors ) + rOutItemSet.Put( SfxBoolItem(nWhichId,m_bConnectBars)); + break; + } + case SCHATTR_GROUP_BARS_PER_AXIS: + { + if( m_bSupportingAxisSideBySide ) + rOutItemSet.Put( SfxBoolItem(nWhichId,m_bGroupBarsPerAxis) ); + break; + } + case SCHATTR_AXIS_FOR_ALL_SERIES: + { + break; + } + case SCHATTR_STARTING_ANGLE: + { + if( m_bSupportingStartingAngle ) + rOutItemSet.Put( SdrAngleItem(SCHATTR_STARTING_ANGLE, Degree100(m_nStartingAngle*100)) ); + break; + } + case SCHATTR_CLOCKWISE: + { + rOutItemSet.Put( SfxBoolItem(nWhichId,m_bClockwise) ); + break; + } + case SCHATTR_MISSING_VALUE_TREATMENT: + { + if( m_aSupportedMissingValueTreatments.hasElements() ) + rOutItemSet.Put( SfxInt32Item( nWhichId, m_nMissingValueTreatment )); + break; + } + case SCHATTR_AVAILABLE_MISSING_VALUE_TREATMENTS: + { + rOutItemSet.Put( SfxIntegerListItem( nWhichId, m_aSupportedMissingValueTreatments ) ); + break; + } + case SCHATTR_INCLUDE_HIDDEN_CELLS: + { + if( m_bSupportingPlottingOfHiddenCells ) + rOutItemSet.Put( SfxBoolItem(nWhichId, m_bIncludeHiddenCells) ); + break; + } + case SCHATTR_HIDE_LEGEND_ENTRY: + { + rOutItemSet.Put(SfxBoolItem(nWhichId, m_bHideLegendEntry)); + break; + } + default: + break; + } +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/StatisticsItemConverter.cxx b/chart2/source/controller/itemsetwrapper/StatisticsItemConverter.cxx new file mode 100644 index 000000000..5e230a434 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/StatisticsItemConverter.cxx @@ -0,0 +1,858 @@ +/* -*- 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 <StatisticsItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <RegressionCurveHelper.hxx> +#include <RegressionCurveModel.hxx> +#include <ErrorBar.hxx> +#include <StatisticsHelper.hxx> +#include <ChartModel.hxx> +#include <unonames.hxx> + +#include <svl/stritem.hxx> +#include <svx/chrtitem.hxx> +#include <svl/intitem.hxx> +#include <rtl/math.hxx> + +#include <com/sun/star/chart2/XInternalDataProvider.hpp> +#include <com/sun/star/chart2/XRegressionCurveContainer.hpp> +#include <com/sun/star/chart/ErrorBarStyle.hpp> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star; + +namespace +{ + +uno::Reference< beans::XPropertySet > lcl_GetErrorBar( + const uno::Reference< beans::XPropertySet > & xProp, bool bYError ) +{ + uno::Reference< beans::XPropertySet > xResult; + + if( xProp.is()) + try + { + ( xProp->getPropertyValue( bYError ? OUString(CHART_UNONAME_ERRORBAR_Y) : OUString(CHART_UNONAME_ERRORBAR_X) ) >>= xResult ); + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } + + return xResult; +} + +uno::Reference< beans::XPropertySet > lcl_GetDefaultErrorBar() +{ + return uno::Reference< beans::XPropertySet >( new ::chart::ErrorBar ); +} + +void lcl_getErrorValues( const uno::Reference< beans::XPropertySet > & xErrorBarProp, + double & rOutPosError, double & rOutNegError ) +{ + if( ! xErrorBarProp.is()) + return; + + try + { + xErrorBarProp->getPropertyValue( "PositiveError" ) >>= rOutPosError; + xErrorBarProp->getPropertyValue( "NegativeError" ) >>= rOutNegError; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +void lcl_getErrorIndicatorValues( + const uno::Reference< beans::XPropertySet > & xErrorBarProp, + bool & rOutShowPosError, bool & rOutShowNegError ) +{ + if( ! xErrorBarProp.is()) + return; + + try + { + xErrorBarProp->getPropertyValue( "ShowPositiveError" ) >>= rOutShowPosError; + xErrorBarProp->getPropertyValue( "ShowNegativeError" ) >>= rOutShowNegError; + } + catch( const uno::Exception & ) + { + DBG_UNHANDLED_EXCEPTION("chart2"); + } +} + +uno::Reference< beans::XPropertySet > lcl_getEquationProperties( + const uno::Reference< beans::XPropertySet > & xSeriesPropSet, const SfxItemSet * pItemSet ) +{ + bool bEquationExists = true; + + // ensure that a trendline is on + if( pItemSet ) + { + if( const SvxChartRegressItem* pRegressionItem = pItemSet->GetItemIfSet( SCHATTR_REGRESSION_TYPE ) ) + { + SvxChartRegress eRegress = pRegressionItem->GetValue(); + bEquationExists = ( eRegress != SvxChartRegress::NONE ); + } + } + + if( bEquationExists ) + { + uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( xSeriesPropSet, uno::UNO_QUERY ); + rtl::Reference< ::chart::RegressionCurveModel > xCurve = + ::chart::RegressionCurveHelper::getFirstCurveNotMeanValueLine( xRegCnt ); + if( xCurve.is()) + { + return xCurve->getEquationProperties(); + } + } + + return uno::Reference< beans::XPropertySet >(); +} + +uno::Reference< beans::XPropertySet > lcl_getCurveProperties( + const uno::Reference< beans::XPropertySet > & xSeriesPropSet, const SfxItemSet * pItemSet ) +{ + bool bExists = true; + + // ensure that a trendline is on + if( pItemSet ) + { + if( const SvxChartRegressItem* pRegressionItem = pItemSet->GetItemIfSet( SCHATTR_REGRESSION_TYPE ) ) + { + SvxChartRegress eRegress = pRegressionItem->GetValue(); + bExists = ( eRegress != SvxChartRegress::NONE ); + } + } + + if( bExists ) + { + uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( xSeriesPropSet, uno::UNO_QUERY ); + uno::Reference< chart2::XRegressionCurve > xCurve( + ::chart::RegressionCurveHelper::getFirstCurveNotMeanValueLine( xRegCnt )); + if( xCurve.is()) + { + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + return xProperties; + } + } + + return uno::Reference< beans::XPropertySet >(); +} + +template <class T, class D> +bool lclConvertToPropertySet(const SfxItemSet& rItemSet, sal_uInt16 nWhichId, const uno::Reference<beans::XPropertySet>& xProperties, const OUString& aPropertyID) +{ + OSL_ASSERT(xProperties.is()); + if( xProperties.is() ) + { + T aValue = static_cast<T>(static_cast<const D&>(rItemSet.Get( nWhichId )).GetValue()); + T aOldValue = aValue; + bool aSuccess = xProperties->getPropertyValue( aPropertyID ) >>= aOldValue; + if (!aSuccess || aOldValue != aValue) + { + xProperties->setPropertyValue( aPropertyID , uno::Any( aValue )); + return true; + } + } + return false; +} + +template <class T, class D> +void lclConvertToItemSet(SfxItemSet& rItemSet, sal_uInt16 nWhichId, const uno::Reference<beans::XPropertySet>& xProperties, const OUString& aPropertyID) +{ + OSL_ASSERT(xProperties.is()); + if( xProperties.is() ) + { + T aValue = static_cast<T>(static_cast<const D&>(rItemSet.Get( nWhichId )).GetValue()); + if(xProperties->getPropertyValue( aPropertyID ) >>= aValue) + { + rItemSet.Put(D( nWhichId, aValue )); + } + } +} + +void lclConvertToItemSetDouble(SfxItemSet& rItemSet, TypedWhichId<SvxDoubleItem> nWhichId, const uno::Reference<beans::XPropertySet>& xProperties, const OUString& aPropertyID) +{ + OSL_ASSERT(xProperties.is()); + if( xProperties.is() ) + { + double aValue = rItemSet.Get( nWhichId ).GetValue(); + if(xProperties->getPropertyValue( aPropertyID ) >>= aValue) + { + rItemSet.Put(SvxDoubleItem( aValue, nWhichId )); + } + } +} + +} // anonymous namespace + +namespace chart::wrapper +{ + +StatisticsItemConverter::StatisticsItemConverter( + const rtl::Reference<::chart::ChartModel> & xModel, + const uno::Reference< beans::XPropertySet > & rPropertySet, + SfxItemPool& rItemPool ) : + ItemConverter( rPropertySet, rItemPool ), + m_xModel( xModel ) +{ +} + +StatisticsItemConverter::~StatisticsItemConverter() +{ +} + +const WhichRangesContainer& StatisticsItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nStatWhichPairs; +} + +bool StatisticsItemConverter::GetItemProperty( + tWhichIdType /* nWhichId */, + tPropertyNameWithMemberId & /* rOutProperty */ ) const +{ + return false; +} + +bool StatisticsItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + + switch( nWhichId ) + { + case SCHATTR_STAT_AVERAGE: + { + uno::Reference< chart2::XRegressionCurveContainer > xRegCnt( + GetPropertySet(), uno::UNO_QUERY ); + bool bOldHasMeanValueLine = RegressionCurveHelper::hasMeanValueLine( xRegCnt ); + + bool bNewHasMeanValueLine = + static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue(); + + if( bOldHasMeanValueLine != bNewHasMeanValueLine ) + { + if( ! bNewHasMeanValueLine ) + RegressionCurveHelper::removeMeanValueLine( xRegCnt ); + else + RegressionCurveHelper::addMeanValueLine( xRegCnt, GetPropertySet() ); + bChanged = true; + } + } + break; + + // Attention !!! This case must be passed before SCHATTR_STAT_PERCENT, + // SCHATTR_STAT_BIGERROR, SCHATTR_STAT_CONSTPLUS, + // SCHATTR_STAT_CONSTMINUS and SCHATTR_STAT_INDICATE + case SCHATTR_STAT_KIND_ERROR: + { + bool bYError = + rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + + uno::Reference< beans::XPropertySet > xErrorBarProp( + lcl_GetErrorBar( GetPropertySet(), bYError )); + + SvxChartKindError eErrorKind = + static_cast< const SvxChartKindErrorItem & >( + rItemSet.Get( nWhichId )).GetValue(); + + if( !xErrorBarProp.is() && eErrorKind == SvxChartKindError::NONE) + { + //nothing to do + } + else + { + sal_Int32 nStyle = css::chart::ErrorBarStyle::NONE; + + switch( eErrorKind ) + { + case SvxChartKindError::NONE: + nStyle = css::chart::ErrorBarStyle::NONE; break; + case SvxChartKindError::Variant: + nStyle = css::chart::ErrorBarStyle::VARIANCE; break; + case SvxChartKindError::Sigma: + nStyle = css::chart::ErrorBarStyle::STANDARD_DEVIATION; break; + case SvxChartKindError::Percent: + nStyle = css::chart::ErrorBarStyle::RELATIVE; break; + case SvxChartKindError::BigError: + nStyle = css::chart::ErrorBarStyle::ERROR_MARGIN; break; + case SvxChartKindError::Const: + nStyle = css::chart::ErrorBarStyle::ABSOLUTE; break; + case SvxChartKindError::StdError: + nStyle = css::chart::ErrorBarStyle::STANDARD_ERROR; break; + case SvxChartKindError::Range: + nStyle = css::chart::ErrorBarStyle::FROM_DATA; break; + } + + if( !xErrorBarProp.is() ) + { + xErrorBarProp = lcl_GetDefaultErrorBar(); + GetPropertySet()->setPropertyValue( bYError ? OUString(CHART_UNONAME_ERRORBAR_Y) : OUString(CHART_UNONAME_ERRORBAR_X), + uno::Any( xErrorBarProp )); + } + + xErrorBarProp->setPropertyValue( "ErrorBarStyle" , uno::Any( nStyle )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_PERCENT: + case SCHATTR_STAT_BIGERROR: + { + OSL_FAIL( "Deprecated item" ); + bool bYError = + rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + + uno::Reference< beans::XPropertySet > xErrorBarProp( + lcl_GetErrorBar( GetPropertySet(), bYError)); + bool bOldHasErrorBar = xErrorBarProp.is(); + + double fValue = + static_cast< const SvxDoubleItem & >( + rItemSet.Get( nWhichId )).GetValue(); + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + + if( bOldHasErrorBar && + ! ( ::rtl::math::approxEqual( fPos, fValue ) && + ::rtl::math::approxEqual( fNeg, fValue ))) + { + xErrorBarProp->setPropertyValue( "PositiveError" , uno::Any( fValue )); + xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_CONSTPLUS: + { + bool bYError = + rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + + uno::Reference< beans::XPropertySet > xErrorBarProp( + lcl_GetErrorBar( GetPropertySet(),bYError)); + bool bOldHasErrorBar = xErrorBarProp.is(); + + double fValue = + static_cast< const SvxDoubleItem & >( + rItemSet.Get( nWhichId )).GetValue(); + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + + if( bOldHasErrorBar && + ! ::rtl::math::approxEqual( fPos, fValue )) + { + xErrorBarProp->setPropertyValue( "PositiveError" , uno::Any( fValue )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_CONSTMINUS: + { + bool bYError = + rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< beans::XPropertySet > xErrorBarProp( + lcl_GetErrorBar( GetPropertySet(),bYError)); + bool bOldHasErrorBar = xErrorBarProp.is(); + + double fValue = + static_cast< const SvxDoubleItem & >( + rItemSet.Get( nWhichId )).GetValue(); + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + + if( bOldHasErrorBar && + ! ::rtl::math::approxEqual( fNeg, fValue )) + { + xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue )); + bChanged = true; + } + } + break; + + case SCHATTR_REGRESSION_TYPE: + { + SvxChartRegress eRegress = + static_cast< const SvxChartRegressItem& >( + rItemSet.Get( nWhichId )).GetValue(); + + uno::Reference< chart2::XRegressionCurve > xCurve( GetPropertySet(), uno::UNO_QUERY ); + uno::Reference< chart2::XRegressionCurveContainer > xContainer( GetPropertySet(), uno::UNO_QUERY ); + + if( eRegress == SvxChartRegress::NONE ) + { + if ( xContainer.is() ) + { + xContainer->removeRegressionCurve( xCurve ); + bChanged = true; + } + } + else + { + if ( xCurve.is() ) + { + SvxChartRegress eOldRegress( + RegressionCurveHelper::getRegressionType(xCurve)); + + if( eOldRegress != eRegress ) + { + xCurve = RegressionCurveHelper::changeRegressionCurveType( + eRegress, + xContainer, + xCurve); + uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY ); + resetPropertySet( xProperties ); + bChanged = true; + } + } + } + } + break; + + case SCHATTR_REGRESSION_DEGREE: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<sal_Int32, SfxInt32Item>(rItemSet, nWhichId, xProperties, "PolynomialDegree"); + } + break; + + case SCHATTR_REGRESSION_PERIOD: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<sal_Int32, SfxInt32Item>(rItemSet, nWhichId, xProperties, "MovingAveragePeriod"); + } + break; + + case SCHATTR_REGRESSION_MOVING_TYPE: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<sal_Int32, SfxInt32Item>(rItemSet, nWhichId, xProperties, "MovingAverageType"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<double, SvxDoubleItem>(rItemSet, nWhichId, xProperties, "ExtrapolateForward"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<double, SvxDoubleItem>(rItemSet, nWhichId, xProperties, "ExtrapolateBackward"); + } + break; + + case SCHATTR_REGRESSION_SET_INTERCEPT: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<bool, SfxBoolItem>(rItemSet, nWhichId, xProperties, "ForceIntercept"); + } + break; + + case SCHATTR_REGRESSION_INTERCEPT_VALUE: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<double, SvxDoubleItem>(rItemSet, nWhichId, xProperties, "InterceptValue"); + } + break; + + case SCHATTR_REGRESSION_CURVE_NAME: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<OUString, SfxStringItem>(rItemSet, nWhichId, xProperties, "CurveName"); + } + break; + + case SCHATTR_REGRESSION_SHOW_EQUATION: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<bool, SfxBoolItem>(rItemSet, nWhichId, xEqProp, "ShowEquation"); + } + break; + + case SCHATTR_REGRESSION_XNAME: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<OUString, SfxStringItem>(rItemSet, nWhichId, xEqProp, "XName"); + } + break; + + case SCHATTR_REGRESSION_YNAME: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<OUString, SfxStringItem>(rItemSet, nWhichId, xEqProp, "YName"); + } + break; + + case SCHATTR_REGRESSION_SHOW_COEFF: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), &rItemSet )); + bChanged = lclConvertToPropertySet<bool, SfxBoolItem>(rItemSet, nWhichId, xEqProp, "ShowCorrelationCoefficient"); + } + break; + + case SCHATTR_STAT_INDICATE: + { + bool bYError = + rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< beans::XPropertySet > xErrorBarProp( + lcl_GetErrorBar( GetPropertySet(),bYError)); + bool bOldHasErrorBar = xErrorBarProp.is(); + + SvxChartIndicate eIndicate = + static_cast< const SvxChartIndicateItem & >( + rItemSet.Get( nWhichId )).GetValue(); + + bool bNewIndPos = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Up ); + bool bNewIndNeg = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Down ); + + bool bShowPos(false), bShowNeg(false); + lcl_getErrorIndicatorValues( xErrorBarProp, bShowPos, bShowNeg ); + + if( bOldHasErrorBar && + ( bShowPos != bNewIndPos || + bShowNeg != bNewIndNeg )) + { + xErrorBarProp->setPropertyValue( "ShowPositiveError" , uno::Any( bNewIndPos )); + xErrorBarProp->setPropertyValue( "ShowNegativeError" , uno::Any( bNewIndNeg )); + bChanged = true; + } + } + break; + + case SCHATTR_STAT_RANGE_POS: + case SCHATTR_STAT_RANGE_NEG: + { + const bool bYError = + rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< chart2::data::XDataSource > xErrorBarSource( lcl_GetErrorBar( GetPropertySet(), bYError), + uno::UNO_QUERY ); + uno::Reference< chart2::data::XDataProvider > xDataProvider; + + if( m_xModel.is()) + xDataProvider.set( m_xModel->getDataProvider()); + if( xErrorBarSource.is() && xDataProvider.is()) + { + OUString aNewRange( static_cast< const SfxStringItem & >( rItemSet.Get( nWhichId )).GetValue()); + bool bApplyNewRange = false; + + bool bIsPositiveValue( nWhichId == SCHATTR_STAT_RANGE_POS ); + if( m_xModel->hasInternalDataProvider()) + { + if( !aNewRange.isEmpty()) + { + uno::Reference< chart2::data::XDataSequence > xSeq( + StatisticsHelper::getErrorDataSequenceFromDataSource( + xErrorBarSource, bIsPositiveValue, bYError )); + if( ! xSeq.is()) + { + // no data range for error bars yet => create + uno::Reference< chart2::XInternalDataProvider > xIntDataProvider( xDataProvider, uno::UNO_QUERY ); + OSL_ASSERT( xIntDataProvider.is()); + if( xIntDataProvider.is()) + { + xIntDataProvider->appendSequence(); + aNewRange = "last"; + bApplyNewRange = true; + } + } + } + } + else + { + uno::Reference< chart2::data::XDataSequence > xSeq( + StatisticsHelper::getErrorDataSequenceFromDataSource( + xErrorBarSource, bIsPositiveValue, bYError )); + bApplyNewRange = + ! ( xSeq.is() && (aNewRange == xSeq->getSourceRangeRepresentation())); + } + + if( bApplyNewRange ) + StatisticsHelper::setErrorDataSequence( + xErrorBarSource, xDataProvider, aNewRange, bIsPositiveValue, bYError ); + } + } + break; + } + + return bChanged; +} + +void StatisticsItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case SCHATTR_STAT_AVERAGE: + rOutItemSet.Put( + SfxBoolItem( nWhichId, + RegressionCurveHelper::hasMeanValueLine( + uno::Reference< chart2::XRegressionCurveContainer >( + GetPropertySet(), uno::UNO_QUERY )))); + break; + + case SCHATTR_STAT_KIND_ERROR: + { + bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + SvxChartKindError eErrorKind = SvxChartKindError::NONE; + uno::Reference< beans::XPropertySet > xErrorBarProp( + lcl_GetErrorBar( GetPropertySet(), bYError)); + if( xErrorBarProp.is() ) + { + sal_Int32 nStyle = 0; + if( xErrorBarProp->getPropertyValue( "ErrorBarStyle" ) >>= nStyle ) + { + switch( nStyle ) + { + case css::chart::ErrorBarStyle::NONE: + break; + case css::chart::ErrorBarStyle::VARIANCE: + eErrorKind = SvxChartKindError::Variant; break; + case css::chart::ErrorBarStyle::STANDARD_DEVIATION: + eErrorKind = SvxChartKindError::Sigma; break; + case css::chart::ErrorBarStyle::ABSOLUTE: + eErrorKind = SvxChartKindError::Const; break; + case css::chart::ErrorBarStyle::RELATIVE: + eErrorKind = SvxChartKindError::Percent; break; + case css::chart::ErrorBarStyle::ERROR_MARGIN: + eErrorKind = SvxChartKindError::BigError; break; + case css::chart::ErrorBarStyle::STANDARD_ERROR: + eErrorKind = SvxChartKindError::StdError; break; + case css::chart::ErrorBarStyle::FROM_DATA: + eErrorKind = SvxChartKindError::Range; break; + } + } + } + rOutItemSet.Put( SvxChartKindErrorItem( eErrorKind, SCHATTR_STAT_KIND_ERROR )); + } + break; + + case SCHATTR_STAT_PERCENT: + { + bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< beans::XPropertySet > xErrorBarProp( lcl_GetErrorBar( GetPropertySet(),bYError)); + if( xErrorBarProp.is()) + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, SCHATTR_STAT_PERCENT )); + } + } + break; + + case SCHATTR_STAT_BIGERROR: + { + bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< beans::XPropertySet > xErrorBarProp( lcl_GetErrorBar( GetPropertySet(),bYError)); + if( xErrorBarProp.is()) + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, SCHATTR_STAT_BIGERROR )); + } + } + break; + + case SCHATTR_STAT_CONSTPLUS: + { + bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< beans::XPropertySet > xErrorBarProp( lcl_GetErrorBar( GetPropertySet(),bYError)); + if( xErrorBarProp.is()) + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( fPos, SCHATTR_STAT_CONSTPLUS )); + } + } + break; + + case SCHATTR_STAT_CONSTMINUS: + { + bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< beans::XPropertySet > xErrorBarProp( lcl_GetErrorBar( GetPropertySet(),bYError)); + if( xErrorBarProp.is()) + { + double fPos(0.0), fNeg(0.0); + lcl_getErrorValues( xErrorBarProp, fPos, fNeg ); + rOutItemSet.Put( SvxDoubleItem( fNeg, SCHATTR_STAT_CONSTMINUS )); + } + } + break; + + case SCHATTR_REGRESSION_TYPE: + { + SvxChartRegress eRegress = + RegressionCurveHelper::getFirstRegressTypeNotMeanValueLine( + uno::Reference< chart2::XRegressionCurveContainer >( + GetPropertySet(), uno::UNO_QUERY ) ); + rOutItemSet.Put( SvxChartRegressItem( eRegress, SCHATTR_REGRESSION_TYPE )); + } + break; + + case SCHATTR_REGRESSION_DEGREE: + { + + uno::Reference<beans::XPropertySet> xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<sal_Int32, SfxInt32Item>(rOutItemSet, nWhichId, xProperties, "PolynomialDegree"); + } + break; + + case SCHATTR_REGRESSION_PERIOD: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<sal_Int32, SfxInt32Item>(rOutItemSet, nWhichId, xProperties, "MovingAveragePeriod"); + } + break; + + case SCHATTR_REGRESSION_MOVING_TYPE: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<sal_Int32, SfxInt32Item>(rOutItemSet, nWhichId, xProperties, "MovingAverageType"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSetDouble(rOutItemSet, SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD, xProperties, "ExtrapolateForward"); + } + break; + + case SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSetDouble(rOutItemSet, SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD, xProperties, "ExtrapolateBackward"); + } + break; + + case SCHATTR_REGRESSION_SET_INTERCEPT: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<bool, SfxBoolItem>(rOutItemSet, nWhichId, xProperties, "ForceIntercept"); + } + break; + + case SCHATTR_REGRESSION_INTERCEPT_VALUE: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSetDouble(rOutItemSet, SCHATTR_REGRESSION_INTERCEPT_VALUE, xProperties, "InterceptValue"); + } + break; + + case SCHATTR_REGRESSION_CURVE_NAME: + { + uno::Reference< beans::XPropertySet > xProperties( lcl_getCurveProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<OUString, SfxStringItem>(rOutItemSet, nWhichId, xProperties, "CurveName"); + } + break; + + case SCHATTR_REGRESSION_SHOW_EQUATION: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<bool, SfxBoolItem>(rOutItemSet, nWhichId, xEqProp, "ShowEquation"); + } + break; + + case SCHATTR_REGRESSION_XNAME: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<OUString, SfxStringItem>(rOutItemSet, nWhichId, xEqProp, "XName"); + } + break; + + case SCHATTR_REGRESSION_YNAME: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<OUString, SfxStringItem>(rOutItemSet, nWhichId, xEqProp, "YName"); + } + break; + + case SCHATTR_REGRESSION_SHOW_COEFF: + { + uno::Reference< beans::XPropertySet > xEqProp( lcl_getEquationProperties( GetPropertySet(), nullptr )); + lclConvertToItemSet<bool, SfxBoolItem>(rOutItemSet, nWhichId, xEqProp, "ShowCorrelationCoefficient"); + } + break; + + case SCHATTR_STAT_INDICATE: + { + bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< beans::XPropertySet > xErrorBarProp( lcl_GetErrorBar( GetPropertySet(),bYError)); + SvxChartIndicate eIndicate = SvxChartIndicate::Both; + if( xErrorBarProp.is()) + { + bool bShowPos(false), bShowNeg(false); + lcl_getErrorIndicatorValues( xErrorBarProp, bShowPos, bShowNeg ); + + if( bShowPos ) + { + if( bShowNeg ) + eIndicate = SvxChartIndicate::Both; + else + eIndicate = SvxChartIndicate::Up; + } + else + { + if( bShowNeg ) + eIndicate = SvxChartIndicate::Down; + else + eIndicate = SvxChartIndicate::NONE; + } + } + rOutItemSet.Put( SvxChartIndicateItem( eIndicate, SCHATTR_STAT_INDICATE )); + } + break; + + case SCHATTR_STAT_RANGE_POS: + case SCHATTR_STAT_RANGE_NEG: + { + bool bYError = + rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue(); + uno::Reference< chart2::data::XDataSource > xErrorBarSource( lcl_GetErrorBar( GetPropertySet(),bYError), + uno::UNO_QUERY ); + if( xErrorBarSource.is()) + { + uno::Reference< chart2::data::XDataSequence > xSeq( + StatisticsHelper::getErrorDataSequenceFromDataSource( + xErrorBarSource, (nWhichId == SCHATTR_STAT_RANGE_POS), bYError )); + if( xSeq.is()) + rOutItemSet.Put( SfxStringItem( nWhichId, xSeq->getSourceRangeRepresentation())); + } + } + break; + } +} + +} // namespace chart + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx new file mode 100644 index 000000000..644d8d80c --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/TextLabelItemConverter.cxx @@ -0,0 +1,723 @@ +/* -*- 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 <TextLabelItemConverter.hxx> +#include <CharacterPropertyItemConverter.hxx> +#include <ChartModel.hxx> +#include <ChartModelHelper.hxx> +#include <ChartType.hxx> +#include <ChartTypeHelper.hxx> +#include <DataSeries.hxx> +#include <DataSeriesHelper.hxx> +#include <DiagramHelper.hxx> +#include <Diagram.hxx> +#include <ItemPropertyMap.hxx> +#include "SchWhichPairs.hxx" +#include <unonames.hxx> + +#include <editeng/brushitem.hxx> +#include <editeng/sizeitem.hxx> +#include <svl/eitem.hxx> +#include <svl/ilstitem.hxx> +#include <svl/intitem.hxx> +#include <svl/stritem.hxx> +#include <svx/tabline.hxx> +#include <svx/sdangitm.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/graph.hxx> +#include <rtl/math.hxx> + +#include <com/sun/star/chart/DataLabelPlacement.hpp> +#include <com/sun/star/chart2/AxisType.hpp> +#include <com/sun/star/chart2/DataPointLabel.hpp> +#include <com/sun/star/chart2/Symbol.hpp> +#include <com/sun/star/chart2/RelativePosition.hpp> +#include <com/sun/star/chart2/XDataSeries.hpp> +#include <memory> + +using namespace com::sun::star; +using namespace com::sun::star::chart2; +using com::sun::star::uno::Reference; + +namespace chart::wrapper { + +namespace { + +const ItemPropertyMapType& getTextLabelPropertyMap() +{ + static ItemPropertyMapType aMap{ + {XATTR_LINESTYLE, {CHART_UNONAME_LABEL_BORDER_STYLE, 0}}, + {XATTR_LINEWIDTH, {CHART_UNONAME_LABEL_BORDER_WIDTH, 0}}, + {XATTR_LINEDASH, {CHART_UNONAME_LABEL_BORDER_DASH, 0}}, + {XATTR_LINECOLOR, {CHART_UNONAME_LABEL_BORDER_COLOR, 0}}, + {XATTR_LINETRANSPARENCE, {CHART_UNONAME_LABEL_BORDER_TRANS, 0}}}; + return aMap; +}; + +sal_Int32 getSymbolStyleForSymbol( const chart2::Symbol& rSymbol ) +{ + sal_Int32 nStyle = SVX_SYMBOLTYPE_UNKNOWN; + switch (rSymbol.Style) + { + case chart2::SymbolStyle_NONE: + nStyle = SVX_SYMBOLTYPE_NONE; + break; + case chart2::SymbolStyle_AUTO: + nStyle = SVX_SYMBOLTYPE_AUTO; + break; + case chart2::SymbolStyle_GRAPHIC: + nStyle = SVX_SYMBOLTYPE_BRUSHITEM; + break; + case chart2::SymbolStyle_STANDARD: + nStyle = rSymbol.StandardSymbol; + break; + case chart2::SymbolStyle_POLYGON: + default: + ; + } + return nStyle; +} + +bool numberFormatFromItemToPropertySet( + sal_uInt16 nWhichId, const SfxItemSet& rItemSet, const uno::Reference<beans::XPropertySet>& xPropertySet, + bool bOverwriteDataPoints ) +{ + bool bChanged = false; + if (!xPropertySet.is()) + return bChanged; + + OUString aPropertyName = (nWhichId == SID_ATTR_NUMBERFORMAT_VALUE) ? OUString(CHART_UNONAME_NUMFMT) : OUString("PercentageNumberFormat"); + sal_uInt16 nSourceWhich = (nWhichId == SID_ATTR_NUMBERFORMAT_VALUE) ? SID_ATTR_NUMBERFORMAT_SOURCE : SCHATTR_PERCENT_NUMBERFORMAT_SOURCE; + + if (rItemSet.GetItemState(nSourceWhich) != SfxItemState::SET) + return bChanged; + + uno::Any aValue; + bool bUseSourceFormat = static_cast<const SfxBoolItem&>(rItemSet.Get(nSourceWhich)).GetValue(); + if (!bUseSourceFormat) + { + SfxItemState aState = rItemSet.GetItemState(nWhichId); + if (aState == SfxItemState::SET) + { + sal_Int32 nFmt = static_cast<sal_Int32>( + static_cast<const SfxUInt32Item&>( + rItemSet.Get(nWhichId)).GetValue()); + aValue <<= nFmt; + } + else + return bChanged; + } + + uno::Any aOldValue = xPropertySet->getPropertyValue(aPropertyName); + if (bOverwriteDataPoints) + { + Reference<chart2::XDataSeries> xSeries(xPropertySet, uno::UNO_QUERY); + if (aValue != aOldValue || + ::chart::DataSeriesHelper::hasAttributedDataPointDifferentValue(xSeries, aPropertyName, aOldValue)) + { + ::chart::DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(xSeries, aPropertyName, aValue); + bChanged = true; + } + } + else if (aOldValue != aValue) + { + xPropertySet->setPropertyValue(aPropertyName, aValue); + bChanged = true; + } + return bChanged; +} + +bool useSourceFormatFromItemToPropertySet( + sal_uInt16 nWhichId, const SfxItemSet& rItemSet, const uno::Reference<beans::XPropertySet>& xPropertySet, + bool bOverwriteDataPoints ) +{ + bool bChanged = false; + if (!xPropertySet.is()) + return bChanged; + OUString aPropertyName = (nWhichId == SID_ATTR_NUMBERFORMAT_SOURCE) ? OUString(CHART_UNONAME_NUMFMT) : OUString("PercentageNumberFormat"); + sal_uInt16 nFormatWhich = (nWhichId == SID_ATTR_NUMBERFORMAT_SOURCE) ? SID_ATTR_NUMBERFORMAT_VALUE : SCHATTR_PERCENT_NUMBERFORMAT_VALUE; + + if (rItemSet.GetItemState(nWhichId) != SfxItemState::SET) + return bChanged; + + uno::Any aNewValue; + bool bUseSourceFormat = static_cast<const SfxBoolItem&>( + rItemSet.Get(nWhichId)).GetValue(); + xPropertySet->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::Any(bUseSourceFormat)); + if (!bUseSourceFormat) + { + SfxItemState aState = rItemSet.GetItemState(nFormatWhich); + if (aState == SfxItemState::SET) + { + sal_Int32 nFormatKey = static_cast<sal_Int32>( + static_cast<const SfxUInt32Item&>( + rItemSet.Get(nFormatWhich)).GetValue()); + aNewValue <<= nFormatKey; + } + else + return bChanged; + } + + uno::Any aOldValue(xPropertySet->getPropertyValue(aPropertyName)); + if (bOverwriteDataPoints) + { + Reference<chart2::XDataSeries> xSeries(xPropertySet, uno::UNO_QUERY); + if (aNewValue != aOldValue || + ::chart::DataSeriesHelper::hasAttributedDataPointDifferentValue(xSeries, aPropertyName, aOldValue)) + { + ::chart::DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(xSeries, aPropertyName, aNewValue); + bChanged = true; + } + } + else if (aOldValue != aNewValue) + { + xPropertySet->setPropertyValue(aPropertyName, aNewValue); + bChanged = true; + } + + return bChanged; +} + +} // anonymous namespace + +TextLabelItemConverter::TextLabelItemConverter( + const rtl::Reference<::chart::ChartModel>& xChartModel, + const uno::Reference<beans::XPropertySet>& rPropertySet, + const rtl::Reference<DataSeries>& xSeries, + SfxItemPool& rItemPool, const awt::Size* pRefSize, + bool bDataSeries, sal_Int32 nNumberFormat, sal_Int32 nPercentNumberFormat ) : + ItemConverter(rPropertySet, rItemPool), + mnNumberFormat(nNumberFormat), + mnPercentNumberFormat(nPercentNumberFormat), + mbDataSeries(bDataSeries), + mbForbidPercentValue(true), + m_xSeries(xSeries) +{ + maConverters.emplace_back(new CharacterPropertyItemConverter(rPropertySet, rItemPool, pRefSize, "ReferencePageSize")); + + rtl::Reference< Diagram > xDiagram(ChartModelHelper::findDiagram(xChartModel)); + rtl::Reference< ChartType > xChartType(DiagramHelper::getChartTypeOfSeries(xDiagram, xSeries)); + bool bFound = false; + bool bAmbiguous = false; + bool bSwapXAndY = DiagramHelper::getVertical(xDiagram, bFound, bAmbiguous); + maAvailableLabelPlacements = ChartTypeHelper::getSupportedLabelPlacements(xChartType, bSwapXAndY, xSeries); + + mbForbidPercentValue = ChartTypeHelper::getAxisType(xChartType, 0) != AxisType::CATEGORY; +} + +TextLabelItemConverter::~TextLabelItemConverter() +{ +} + +void TextLabelItemConverter::FillItemSet( SfxItemSet& rOutItemSet ) const +{ + for( const auto& pConv : maConverters ) + pConv->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet(rOutItemSet); +} + +bool TextLabelItemConverter::ApplyItemSet( const SfxItemSet& rItemSet ) +{ + bool bResult = false; + + for( const auto& pConv: maConverters ) + bResult = pConv->ApplyItemSet( rItemSet ) || bResult; + + // own items + return ItemConverter::ApplyItemSet(rItemSet) || bResult; +} + +const WhichRangesContainer& TextLabelItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nTextLabelWhichPairs; +} + +bool TextLabelItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId& rOutProperty ) const +{ + const ItemPropertyMapType& rMap = getTextLabelPropertyMap(); + ItemPropertyMapType::const_iterator it = rMap.find(nWhichId); + + if (it == rMap.end()) + return false; + + rOutProperty = it->second; + return true; +} + +bool TextLabelItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet& rItemSet ) +{ + bool bChanged = false; + + switch (nWhichId) + { + case SCHATTR_DATADESCR_SHOW_NUMBER: + case SCHATTR_DATADESCR_SHOW_PERCENTAGE: + case SCHATTR_DATADESCR_SHOW_CATEGORY: + case SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME: + case SCHATTR_DATADESCR_SHOW_SYMBOL: + { + const SfxBoolItem& rItem = static_cast<const SfxBoolItem&>(rItemSet.Get(nWhichId)); + + uno::Any aOldValue = GetPropertySet()->getPropertyValue(CHART_UNONAME_LABEL); + chart2::DataPointLabel aLabel; + if (aOldValue >>= aLabel) + { + sal_Bool& rValue = (nWhichId == SCHATTR_DATADESCR_SHOW_NUMBER) ? aLabel.ShowNumber : ( + (nWhichId == SCHATTR_DATADESCR_SHOW_PERCENTAGE) ? aLabel.ShowNumberInPercent : ( + (nWhichId == SCHATTR_DATADESCR_SHOW_CATEGORY) ? aLabel.ShowCategoryName : + (nWhichId == SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME) ? aLabel.ShowSeriesName : aLabel.ShowLegendSymbol)); + bool bOldValue = rValue; + rValue = rItem.GetValue(); + if (mbDataSeries) + { + Reference<chart2::XDataSeries> xSeries(GetPropertySet(), uno::UNO_QUERY); + if (bOldValue != bool(rValue) || + DataSeriesHelper::hasAttributedDataPointDifferentValue(xSeries, CHART_UNONAME_LABEL, aOldValue)) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(xSeries, CHART_UNONAME_LABEL, uno::Any(aLabel)); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(xSeries, CHART_UNONAME_CUSTOM_LABEL_FIELDS, uno::Any()); + bChanged = true; + } + } + else if (bOldValue != bool(rValue)) + { + GetPropertySet()->setPropertyValue(CHART_UNONAME_LABEL, uno::Any(aLabel)); + bChanged = true; + } + } + } + break; + case SID_ATTR_NUMBERFORMAT_VALUE: + case SCHATTR_PERCENT_NUMBERFORMAT_VALUE: //fall through intended + { + bChanged = numberFormatFromItemToPropertySet(nWhichId, rItemSet, GetPropertySet(), mbDataSeries); + } + break; + case SID_ATTR_NUMBERFORMAT_SOURCE: + case SCHATTR_PERCENT_NUMBERFORMAT_SOURCE: //fall through intended + { + bChanged = useSourceFormatFromItemToPropertySet(nWhichId, rItemSet, GetPropertySet(), mbDataSeries); + } + break; + case SCHATTR_DATADESCR_SEPARATOR: + { + OUString aNewValue = static_cast<const SfxStringItem&>(rItemSet.Get(nWhichId)).GetValue(); + try + { + OUString aOldValue; + GetPropertySet()->getPropertyValue("LabelSeparator") >>= aOldValue; + if (mbDataSeries) + { + Reference<chart2::XDataSeries> xSeries(GetPropertySet(), uno::UNO_QUERY); + if (aOldValue != aNewValue || + DataSeriesHelper::hasAttributedDataPointDifferentValue(xSeries, "LabelSeparator", uno::Any(aOldValue))) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(xSeries, "LabelSeparator", uno::Any(aNewValue)); + bChanged = true; + } + } + else if (aOldValue != aNewValue) + { + GetPropertySet()->setPropertyValue("LabelSeparator", uno::Any(aNewValue)); + bChanged = true; + } + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + } + break; + case SCHATTR_DATADESCR_WRAP_TEXT: + { + + try + { + bool bNew = static_cast< const SfxBoolItem & >( rItemSet.Get( nWhichId )).GetValue(); + bool bOld = false; + GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bOld; + if( mbDataSeries ) + { + Reference< chart2::XDataSeries > xSeries( GetPropertySet(), uno::UNO_QUERY); + if( bOld!=bNew || + DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries, "TextWordWrap", uno::Any( bOld ) ) ) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, "TextWordWrap", uno::Any( bNew ) ); + bChanged = true; + } + } + else if( bOld!=bNew ) + { + GetPropertySet()->setPropertyValue( "TextWordWrap", uno::Any( bNew )); + bChanged = true; + } + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + case SCHATTR_DATADESCR_PLACEMENT: + { + try + { + sal_Int32 nNew = static_cast<const SfxInt32Item&>(rItemSet.Get(nWhichId)).GetValue(); + sal_Int32 nOld = -1; + RelativePosition aCustomLabelPosition; + GetPropertySet()->getPropertyValue("LabelPlacement") >>= nOld; + if (mbDataSeries) + { + Reference<chart2::XDataSeries> xSeries(GetPropertySet(), uno::UNO_QUERY); + if (nOld != nNew || + DataSeriesHelper::hasAttributedDataPointDifferentValue(xSeries, "LabelPlacement", uno::Any(nOld))) + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(xSeries, "LabelPlacement", uno::Any(nNew)); + bChanged = true; + } + } + else if (nOld != nNew || (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition)) + { + GetPropertySet()->setPropertyValue("LabelPlacement", uno::Any(nNew)); + GetPropertySet()->setPropertyValue("CustomLabelPosition", uno::Any()); + bChanged = true; + } + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + case SCHATTR_STYLE_SYMBOL: + { + sal_Int32 nStyle = + static_cast<const SfxInt32Item&>( + rItemSet.Get(nWhichId)).GetValue(); + chart2::Symbol aSymbol; + + GetPropertySet()->getPropertyValue("Symbol") >>= aSymbol; + sal_Int32 nOldStyle = getSymbolStyleForSymbol(aSymbol); + + if (nStyle != nOldStyle) + { + bool bDeleteSymbol = false; + switch (nStyle) + { + case SVX_SYMBOLTYPE_NONE: + aSymbol.Style = chart2::SymbolStyle_NONE; + break; + case SVX_SYMBOLTYPE_AUTO: + aSymbol.Style = chart2::SymbolStyle_AUTO; + break; + case SVX_SYMBOLTYPE_BRUSHITEM: + aSymbol.Style = chart2::SymbolStyle_GRAPHIC; + break; + case SVX_SYMBOLTYPE_UNKNOWN: + bDeleteSymbol = true; + break; + + default: + aSymbol.Style = chart2::SymbolStyle_STANDARD; + aSymbol.StandardSymbol = nStyle; + } + + if (bDeleteSymbol) + GetPropertySet()->setPropertyValue("Symbol", uno::Any()); + else + GetPropertySet()->setPropertyValue("Symbol", uno::Any(aSymbol)); + bChanged = true; + } + } + break; + case SCHATTR_SYMBOL_SIZE: + { + Size aSize = static_cast<const SvxSizeItem&>( + rItemSet.Get(nWhichId)).GetSize(); + chart2::Symbol aSymbol; + + GetPropertySet()->getPropertyValue("Symbol") >>= aSymbol; + if (aSize.getWidth() != aSymbol.Size.Width || + aSize.getHeight() != aSymbol.Size.Height) + { + aSymbol.Size.Width = aSize.getWidth(); + aSymbol.Size.Height = aSize.getHeight(); + + GetPropertySet()->setPropertyValue("Symbol", uno::Any(aSymbol)); + bChanged = true; + } + } + break; + case SCHATTR_SYMBOL_BRUSH: + { + const SvxBrushItem& rBrshItem(static_cast<const SvxBrushItem&>( + rItemSet.Get(nWhichId))); + uno::Any aXGraphicAny; + const Graphic* pGraphic(rBrshItem.GetGraphic()); + if (pGraphic) + { + uno::Reference<graphic::XGraphic> xGraphic(pGraphic->GetXGraphic()); + if (xGraphic.is()) + { + aXGraphicAny <<= xGraphic; + chart2::Symbol aSymbol; + GetPropertySet()->getPropertyValue("Symbol") >>= aSymbol; + if (aSymbol.Graphic != xGraphic) + { + aSymbol.Graphic = xGraphic; + GetPropertySet()->setPropertyValue("Symbol", uno::Any(aSymbol)); + bChanged = true; + } + } + } + } + break; + case SCHATTR_TEXT_DEGREES: + { + double fValue = static_cast<double>( + static_cast<const SdrAngleItem&>( + rItemSet.Get(nWhichId)).GetValue().get()) / 100.0; + double fOldValue = 0.0; + bool bPropExisted = + (GetPropertySet()->getPropertyValue("TextRotation") >>= fOldValue); + + if (!bPropExisted || fOldValue != fValue) + { + GetPropertySet()->setPropertyValue("TextRotation", uno::Any(fValue)); + bChanged = true; + } + } + break; + case SCHATTR_DATADESCR_CUSTOM_LEADER_LINES: + { + try + { + bool bNew = static_cast<const SfxBoolItem&>(rItemSet.Get(nWhichId)).GetValue(); + bool bOld = true; + if( (m_xSeries->getPropertyValue("ShowCustomLeaderLines") >>= bOld) && bOld != bNew ) + { + m_xSeries->setPropertyValue("ShowCustomLeaderLines", uno::Any(bNew)); + bChanged = true; + } + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + } + break; + } + + return bChanged; +} + +void TextLabelItemConverter::FillSpecialItem( sal_uInt16 nWhichId, SfxItemSet& rOutItemSet ) const +{ + switch (nWhichId) + { + case SCHATTR_DATADESCR_SHOW_NUMBER: + case SCHATTR_DATADESCR_SHOW_PERCENTAGE: + case SCHATTR_DATADESCR_SHOW_CATEGORY: + case SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME: + case SCHATTR_DATADESCR_SHOW_SYMBOL: + { + chart2::DataPointLabel aLabel; + if (GetPropertySet()->getPropertyValue(CHART_UNONAME_LABEL) >>= aLabel) + { + bool bValue = (nWhichId == SCHATTR_DATADESCR_SHOW_NUMBER) ? aLabel.ShowNumber : ( + (nWhichId == SCHATTR_DATADESCR_SHOW_PERCENTAGE) ? aLabel.ShowNumberInPercent : ( + (nWhichId == SCHATTR_DATADESCR_SHOW_CATEGORY) ? aLabel.ShowCategoryName : ( + (nWhichId == SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME) ? aLabel.ShowSeriesName : aLabel.ShowLegendSymbol))); + + rOutItemSet.Put(SfxBoolItem(nWhichId, bValue)); + + if (mbDataSeries) + { + if (DataSeriesHelper::hasAttributedDataPointDifferentValue( + Reference<chart2::XDataSeries>(GetPropertySet(), uno::UNO_QUERY), CHART_UNONAME_LABEL, uno::Any(aLabel))) + { + rOutItemSet.InvalidateItem(nWhichId); + } + } + } + } + break; + case SID_ATTR_NUMBERFORMAT_VALUE: + { + sal_Int32 nKey = 0; + if (!(GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nKey)) + nKey = mnNumberFormat; + rOutItemSet.Put(SfxUInt32Item(nWhichId, nKey)); + } + break; + case SCHATTR_PERCENT_NUMBERFORMAT_VALUE: + { + sal_Int32 nKey = 0; + if (!(GetPropertySet()->getPropertyValue("PercentageNumberFormat") >>= nKey)) + nKey = mnPercentNumberFormat; + rOutItemSet.Put(SfxUInt32Item(nWhichId, nKey)); + } + break; + case SID_ATTR_NUMBERFORMAT_SOURCE: + { + bool bUseSourceFormat = false; + try + { + GetPropertySet()->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT) >>= bUseSourceFormat; + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + bool bNumberFormatIsSet = GetPropertySet()->getPropertyValue(CHART_UNONAME_NUMFMT).hasValue() && !bUseSourceFormat; + rOutItemSet.Put(SfxBoolItem(nWhichId, !bNumberFormatIsSet)); + } + break; + case SCHATTR_PERCENT_NUMBERFORMAT_SOURCE: + { + bool bUseSourceFormat = false; + try + { + GetPropertySet()->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT) >>= bUseSourceFormat; + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + bool bNumberFormatIsSet = GetPropertySet()->getPropertyValue("PercentageNumberFormat").hasValue() && !bUseSourceFormat; + rOutItemSet.Put(SfxBoolItem(nWhichId, !bNumberFormatIsSet)); + } + break; + case SCHATTR_DATADESCR_SEPARATOR: + { + try + { + OUString aValue; + GetPropertySet()->getPropertyValue("LabelSeparator") >>= aValue; + rOutItemSet.Put(SfxStringItem(nWhichId, aValue)); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + case SCHATTR_DATADESCR_WRAP_TEXT: + { + try + { + bool bValue = false; + GetPropertySet()->getPropertyValue( "TextWordWrap" ) >>= bValue; + rOutItemSet.Put( SfxBoolItem( nWhichId, bValue )); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + case SCHATTR_DATADESCR_PLACEMENT: + { + try + { + sal_Int32 nPlacement = 0; + RelativePosition aCustomLabelPosition; + if (!mbDataSeries && (GetPropertySet()->getPropertyValue("CustomLabelPosition") >>= aCustomLabelPosition)) + rOutItemSet.Put(SfxInt32Item(nWhichId, css::chart::DataLabelPlacement::CUSTOM)); + else if (GetPropertySet()->getPropertyValue("LabelPlacement") >>= nPlacement) + rOutItemSet.Put(SfxInt32Item(nWhichId, nPlacement)); + else if (maAvailableLabelPlacements.hasElements()) + rOutItemSet.Put(SfxInt32Item(nWhichId, maAvailableLabelPlacements[0])); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", "" ); + } + } + break; + case SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS: + { + rOutItemSet.Put(SfxIntegerListItem(nWhichId, maAvailableLabelPlacements)); + } + break; + case SCHATTR_DATADESCR_NO_PERCENTVALUE: + { + rOutItemSet.Put(SfxBoolItem(nWhichId, mbForbidPercentValue)); + } + break; + case SCHATTR_DATADESCR_CUSTOM_LEADER_LINES: + { + try + { + bool bValue = true; + if( m_xSeries->getPropertyValue( "ShowCustomLeaderLines" ) >>= bValue ) + rOutItemSet.Put(SfxBoolItem(nWhichId, bValue)); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("chart2", ""); + } + } + break; + case SCHATTR_STYLE_SYMBOL: + { + chart2::Symbol aSymbol; + if (GetPropertySet()->getPropertyValue("Symbol") >>= aSymbol) + rOutItemSet.Put(SfxInt32Item(nWhichId, getSymbolStyleForSymbol(aSymbol))); + } + break; + case SCHATTR_SYMBOL_SIZE: + { + chart2::Symbol aSymbol; + if (GetPropertySet()->getPropertyValue("Symbol") >>= aSymbol) + rOutItemSet.Put( + SvxSizeItem(nWhichId, Size(aSymbol.Size.Width, aSymbol.Size.Height))); + } + break; + case SCHATTR_SYMBOL_BRUSH: + { + chart2::Symbol aSymbol; + if ((GetPropertySet()->getPropertyValue("Symbol") >>= aSymbol) + && aSymbol.Graphic.is()) + { + rOutItemSet.Put( + SvxBrushItem(Graphic(aSymbol.Graphic), GPOS_MM, SCHATTR_SYMBOL_BRUSH)); + } + } + break; + case SCHATTR_TEXT_DEGREES: + { + double fValue = 0; + + if (GetPropertySet()->getPropertyValue("TextRotation") >>= fValue) + { + rOutItemSet.Put( + SdrAngleItem(SCHATTR_TEXT_DEGREES, Degree100(static_cast<sal_Int32>(rtl::math::round(fValue * 100.0))))); + } + } + break; + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/controller/itemsetwrapper/TitleItemConverter.cxx b/chart2/source/controller/itemsetwrapper/TitleItemConverter.cxx new file mode 100644 index 000000000..7a3f57af5 --- /dev/null +++ b/chart2/source/controller/itemsetwrapper/TitleItemConverter.cxx @@ -0,0 +1,210 @@ +/* -*- 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 <TitleItemConverter.hxx> +#include "SchWhichPairs.hxx" +#include <ItemPropertyMap.hxx> +#include <GraphicPropertyItemConverter.hxx> +#include <CharacterPropertyItemConverter.hxx> +#include <MultipleItemConverter.hxx> +#include <svx/sdangitm.hxx> +#include <rtl/math.hxx> + +#include <com/sun/star/chart2/XTitle.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <memory> + +using namespace ::com::sun::star; + +namespace chart::wrapper { + +namespace { + +ItemPropertyMapType & lcl_GetTitlePropertyMap() +{ + static ItemPropertyMapType aTitlePropertyMap{ + {SCHATTR_TEXT_STACKED, {"StackCharacters", 0}}}; + return aTitlePropertyMap; +}; + +class FormattedStringsConverter : public MultipleItemConverter +{ +public: + FormattedStringsConverter( + const uno::Sequence< uno::Reference< chart2::XFormattedString > > & aStrings, + SfxItemPool & rItemPool, + const awt::Size* pRefSize, + const uno::Reference< beans::XPropertySet > & xParentProp ); + +protected: + virtual const WhichRangesContainer& GetWhichPairs() const override; +}; + +} // anonymous namespace + +FormattedStringsConverter::FormattedStringsConverter( + const uno::Sequence< uno::Reference< chart2::XFormattedString > > & aStrings, + SfxItemPool & rItemPool, + const awt::Size* pRefSize, + const uno::Reference< beans::XPropertySet > & xParentProp ) : + MultipleItemConverter( rItemPool ) +{ + bool bHasRefSize = (pRefSize && xParentProp.is()); + for( uno::Reference< chart2::XFormattedString > const & formattedStr : aStrings ) + { + uno::Reference< beans::XPropertySet > xProp( formattedStr, uno::UNO_QUERY ); + if( xProp.is()) + { + if( bHasRefSize ) + m_aConverters.emplace_back( + new CharacterPropertyItemConverter( + xProp, rItemPool, pRefSize, "ReferencePageSize", xParentProp)); + else + m_aConverters.emplace_back( new CharacterPropertyItemConverter( xProp, rItemPool )); + } + } +} + +const WhichRangesContainer& FormattedStringsConverter::GetWhichPairs() const +{ + return nCharacterPropertyWhichPairs; +} + +TitleItemConverter::TitleItemConverter( + const uno::Reference<beans::XPropertySet> & rPropertySet, + SfxItemPool& rItemPool, + SdrModel& rDrawModel, + const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory, + const awt::Size* pRefSize ) : + ItemConverter( rPropertySet, rItemPool ) +{ + m_aConverters.emplace_back( new GraphicPropertyItemConverter( + rPropertySet, rItemPool, rDrawModel, + xNamedPropertyContainerFactory, + GraphicObjectType::LineAndFillProperties )); + + // CharacterProperties are not at the title but at its contained XFormattedString objects + // take the first formatted string in the sequence + uno::Reference< chart2::XTitle > xTitle( rPropertySet, uno::UNO_QUERY ); + if( xTitle.is()) + { + uno::Sequence< uno::Reference< chart2::XFormattedString > > aStringSeq( xTitle->getText()); + if( aStringSeq.hasElements() ) + { + m_aConverters.emplace_back( + new FormattedStringsConverter( aStringSeq, rItemPool, pRefSize, rPropertySet )); + } + } +} + +TitleItemConverter::~TitleItemConverter() +{ +} + +void TitleItemConverter::FillItemSet( SfxItemSet & rOutItemSet ) const +{ + for( const auto& pConv : m_aConverters ) + pConv->FillItemSet( rOutItemSet ); + + // own items + ItemConverter::FillItemSet( rOutItemSet ); +} + +bool TitleItemConverter::ApplyItemSet( const SfxItemSet & rItemSet ) +{ + bool bResult = false; + + for( const auto& pConv : m_aConverters ) + bResult = pConv->ApplyItemSet( rItemSet ) || bResult; + + // own items + return ItemConverter::ApplyItemSet( rItemSet ) || bResult; +} + +const WhichRangesContainer& TitleItemConverter::GetWhichPairs() const +{ + // must span all used items! + return nTitleWhichPairs; +} + +bool TitleItemConverter::GetItemProperty( tWhichIdType nWhichId, tPropertyNameWithMemberId & rOutProperty ) const +{ + ItemPropertyMapType & rMap( lcl_GetTitlePropertyMap()); + ItemPropertyMapType::const_iterator aIt( rMap.find( nWhichId )); + + if( aIt == rMap.end()) + return false; + + rOutProperty =(*aIt).second; + return true; +} + +bool TitleItemConverter::ApplySpecialItem( + sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) +{ + bool bChanged = false; + + switch( nWhichId ) + { + case SCHATTR_TEXT_DEGREES: + { + // convert int to double (divided by 100) + double fVal = static_cast< double >( + static_cast< const SdrAngleItem & >( + rItemSet.Get( nWhichId )).GetValue().get()) / 100.0; + double fOldVal = 0.0; + bool bPropExisted = + ( GetPropertySet()->getPropertyValue( "TextRotation" ) >>= fOldVal ); + + if( ! bPropExisted || fOldVal != fVal ) + { + GetPropertySet()->setPropertyValue( "TextRotation" , uno::Any( fVal )); + bChanged = true; + } + } + break; + } + + return bChanged; +} + +void TitleItemConverter::FillSpecialItem( + sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const +{ + switch( nWhichId ) + { + case SCHATTR_TEXT_DEGREES: + { + // convert double to int (times 100) + double fVal = 0; + + if( GetPropertySet()->getPropertyValue( "TextRotation" ) >>= fVal ) + { + rOutItemSet.Put( SdrAngleItem( SCHATTR_TEXT_DEGREES, Degree100(static_cast< sal_Int32 >( + ::rtl::math::round( fVal * 100.0 ) ) ))); + } + } + break; + } +} + +} // namespace chart::wrapper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |