Files
loongoffice/chart2/source/view/main/PropertyMapper.cxx
Kohei Yoshida f1531cdaae bnc#885825: Support borders around data labels.
Change-Id: Ib141413e523cbf73746876f727e9f80dda9f5f7c
2014-07-26 16:26:08 -04:00

500 lines
21 KiB
C++

/* -*- 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 "PropertyMapper.hxx"
#include "ContainerHelper.hxx"
#include "macros.hxx"
#include <unonames.hxx>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
namespace chart
{
using namespace ::com::sun::star;
namespace
{
void lcl_overwriteOrAppendValues(
tPropertyNameValueMap &rMap, const tPropertyNameValueMap& rOverwriteMap )
{
tPropertyNameValueMap::const_iterator aIt( rOverwriteMap.begin() );
tPropertyNameValueMap::const_iterator aEnd( rOverwriteMap.end() );
for( ; aIt != aEnd; ++aIt )
rMap[ aIt->first ] = aIt->second;
}
} // anonymous namespace
void PropertyMapper::setMappedProperties(
const uno::Reference< beans::XPropertySet >& xTarget
, const uno::Reference< beans::XPropertySet >& xSource
, const tPropertyNameMap& rMap
, tPropertyNameValueMap* pOverwriteMap )
{
if( !xTarget.is() || !xSource.is() )
return;
tNameSequence aNames;
tAnySequence aValues;
getMultiPropertyLists(aNames, aValues, xSource, rMap );
if(pOverwriteMap && (aNames.getLength() == aValues.getLength()))
{
tPropertyNameValueMap aNewMap;
for( sal_Int32 nI=0; nI<aNames.getLength(); ++nI )
aNewMap[ aNames[nI] ] = aValues[nI];
lcl_overwriteOrAppendValues( aNewMap, *pOverwriteMap );
aNames = ContainerHelper::MapKeysToSequence( aNewMap );
aValues = ContainerHelper::MapValuesToSequence( aNewMap );
}
PropertyMapper::setMultiProperties( aNames, aValues, xTarget );
}
void PropertyMapper::getValueMap(
tPropertyNameValueMap& rValueMap
, const tPropertyNameMap& rNameMap
, const uno::Reference< beans::XPropertySet >& xSourceProp
)
{
tPropertyNameMap::const_iterator aIt( rNameMap.begin() );
tPropertyNameMap::const_iterator aEnd( rNameMap.end() );
uno::Reference< beans::XMultiPropertySet > xMultiPropSet(xSourceProp, uno::UNO_QUERY);
if(false && xMultiPropSet.is())
{
uno::Sequence< rtl::OUString > aPropSourceNames(rNameMap.size());
uno::Sequence< rtl::OUString > aPropTargetNames(rNameMap.size());
for(sal_Int32 i = 0; aIt != aEnd; ++aIt, ++i)
{
aPropTargetNames[i] = aIt->first;
aPropSourceNames[i] = aIt->second;
}
uno::Sequence< uno::Any > xValues = xMultiPropSet->getPropertyValues(aPropSourceNames);
for(sal_Int32 i = 0, n = rNameMap.size(); i < n; ++i)
{
if( xValues[i].hasValue() )
rValueMap.insert( tPropertyNameValueMap::value_type( aPropTargetNames[i], xValues[i] ) );
}
}
else
{
for( ; aIt != aEnd; ++aIt )
{
OUString aTarget = aIt->first;
OUString aSource = aIt->second;
try
{
uno::Any aAny( xSourceProp->getPropertyValue(aSource) );
if( aAny.hasValue() )
rValueMap.insert( tPropertyNameValueMap::value_type( aTarget, aAny ) );
}
catch( const uno::Exception& e )
{
ASSERT_EXCEPTION( e );
}
}
}
}
void PropertyMapper::getMultiPropertyLists(
tNameSequence& rNames
, tAnySequence& rValues
, const uno::Reference< beans::XPropertySet >& xSourceProp
, const tPropertyNameMap& rNameMap
)
{
tPropertyNameValueMap aValueMap;
getValueMap( aValueMap, rNameMap, xSourceProp );
getMultiPropertyListsFromValueMap( rNames, rValues, aValueMap );
}
void PropertyMapper::getMultiPropertyListsFromValueMap(
tNameSequence& rNames
, tAnySequence& rValues
, const tPropertyNameValueMap& rValueMap
)
{
sal_Int32 nPropertyCount = rValueMap.size();
rNames.realloc(nPropertyCount);
rValues.realloc(nPropertyCount);
//fill sequences
tPropertyNameValueMap::const_iterator aValueIt( rValueMap.begin() );
tPropertyNameValueMap::const_iterator aValueEnd( rValueMap.end() );
sal_Int32 nN=0;
for( ; aValueIt != aValueEnd; ++aValueIt )
{
const uno::Any& rAny = aValueIt->second;
if( rAny.hasValue() )
{
//do not set empty anys because of performance (otherwise SdrAttrObj::ItemChange will take much longer)
rNames[nN] = aValueIt->first;
rValues[nN] = rAny;
++nN;
}
}
//reduce to real property count
rNames.realloc(nN);
rValues.realloc(nN);
}
uno::Any* PropertyMapper::getValuePointer( tAnySequence& rPropValues
, const tNameSequence& rPropNames
, const OUString& rPropName )
{
sal_Int32 nCount = rPropNames.getLength();
for( sal_Int32 nN = 0; nN < nCount; nN++ )
{
if(rPropNames[nN].equals(rPropName))
return &rPropValues[nN];
}
return NULL;
}
uno::Any* PropertyMapper::getValuePointerForLimitedSpace( tAnySequence& rPropValues
, const tNameSequence& rPropNames
, bool bLimitedHeight)
{
return PropertyMapper::getValuePointer( rPropValues, rPropNames
, bLimitedHeight ? OUString("TextMaximumFrameHeight") : OUString("TextMaximumFrameWidth") );
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForCharacterProperties()
{
//shape property -- chart model object property
static tMakePropertyNameMap m_aShapePropertyMapForCharacterProperties =
tMakePropertyNameMap
( "CharColor", "CharColor" )
( "CharContoured", "CharContoured" )
( "CharEmphasis", "CharEmphasis" )//the service style::CharacterProperties describes a property called 'CharEmphasize' which is nowhere implemented
( "CharFontFamily", "CharFontFamily" )
( "CharFontFamilyAsian", "CharFontFamilyAsian" )
( "CharFontFamilyComplex", "CharFontFamilyComplex" )
( "CharFontCharSet", "CharFontCharSet" )
( "CharFontCharSetAsian", "CharFontCharSetAsian" )
( "CharFontCharSetComplex", "CharFontCharSetComplex" )
( "CharFontName", "CharFontName" )
( "CharFontNameAsian", "CharFontNameAsian" )
( "CharFontNameComplex", "CharFontNameComplex" )
( "CharFontPitch", "CharFontPitch" )
( "CharFontPitchAsian", "CharFontPitchAsian" )
( "CharFontPitchComplex", "CharFontPitchComplex" )
( "CharFontStyleName", "CharFontStyleName" )
( "CharFontStyleNameAsian", "CharFontStyleNameAsian" )
( "CharFontStyleNameComplex", "CharFontStyleNameComplex" )
( "CharHeight", "CharHeight" )
( "CharHeightAsian", "CharHeightAsian" )
( "CharHeightComplex", "CharHeightComplex" )
( "CharKerning", "CharKerning" )
( "CharLocale", "CharLocale" )
( "CharLocaleAsian", "CharLocaleAsian" )
( "CharLocaleComplex", "CharLocaleComplex" )
( "CharPosture", "CharPosture" )
( "CharPostureAsian", "CharPostureAsian" )
( "CharPostureComplex", "CharPostureComplex" )
( "CharRelief", "CharRelief" )
( "CharShadowed", "CharShadowed" )
( "CharStrikeout", "CharStrikeout" )
( "CharUnderline", "CharUnderline" )
( "CharUnderlineColor", "CharUnderlineColor" )
( "CharUnderlineHasColor", "CharUnderlineHasColor" )
( "CharOverline", "CharOverline" )
( "CharOverlineColor", "CharOverlineColor" )
( "CharOverlineHasColor", "CharOverlineHasColor" )
( "CharWeight", "CharWeight" )
( "CharWeightAsian", "CharWeightAsian" )
( "CharWeightComplex", "CharWeightComplex" )
( "CharWordMode", "CharWordMode" )
( "WritingMode", "WritingMode" )
( "ParaIsCharacterDistance", "ParaIsCharacterDistance" )
;
return m_aShapePropertyMapForCharacterProperties;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForParagraphProperties()
{
//shape property -- chart model object property
static tMakePropertyNameMap m_aShapePropertyMapForParagraphProperties =
tMakePropertyNameMap
( "ParaAdjust", "ParaAdjust" )
( "ParaBottomMargin", "ParaBottomMargin" )
( "ParaIsHyphenation", "ParaIsHyphenation" )
( "ParaLastLineAdjust", "ParaLastLineAdjust" )
( "ParaLeftMargin", "ParaLeftMargin" )
( "ParaRightMargin", "ParaRightMargin" )
( "ParaTopMargin", "ParaTopMargin" )
;
return m_aShapePropertyMapForParagraphProperties;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForFillProperties()
{
//shape property -- chart model object property
static tMakePropertyNameMap m_aShapePropertyMapForFillProperties =
tMakePropertyNameMap
( "FillBackground", "FillBackground" )
( "FillBitmapName", "FillBitmapName" )
( "FillColor", "FillColor" )
( "FillGradientName", "FillGradientName" )
( "FillGradientStepCount", "FillGradientStepCount" )
( "FillHatchName", "FillHatchName" )
( "FillStyle", "FillStyle" )
( "FillTransparence", "FillTransparence" )
( "FillTransparenceGradientName", "FillTransparenceGradientName" )
//bitmap properties
( "FillBitmapMode", "FillBitmapMode" )
( "FillBitmapSizeX", "FillBitmapSizeX" )
( "FillBitmapSizeY", "FillBitmapSizeY" )
( "FillBitmapLogicalSize", "FillBitmapLogicalSize" )
( "FillBitmapOffsetX", "FillBitmapOffsetX" )
( "FillBitmapOffsetY", "FillBitmapOffsetY" )
( "FillBitmapRectanglePoint", "FillBitmapRectanglePoint" )
( "FillBitmapPositionOffsetX", "FillBitmapPositionOffsetX" )
( "FillBitmapPositionOffsetY", "FillBitmapPositionOffsetY" )
;
return m_aShapePropertyMapForFillProperties;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForLineProperties()
{
//shape property -- chart model object property
static tMakePropertyNameMap m_aShapePropertyMapForLineProperties =
tMakePropertyNameMap
( "LineColor", "LineColor" )
( "LineDashName", "LineDashName" )
( "LineJoint", "LineJoint" )
( "LineStyle", "LineStyle" )
( "LineTransparence", "LineTransparence" )
( "LineWidth", "LineWidth" )
;
return m_aShapePropertyMapForLineProperties;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForFillAndLineProperties()
{
static tMakePropertyNameMap m_aShapePropertyMapForFillAndLineProperties =
tMakePropertyNameMap
( PropertyMapper::getPropertyNameMapForFillProperties() )
( PropertyMapper::getPropertyNameMapForLineProperties() )
;
return m_aShapePropertyMapForFillAndLineProperties;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForTextShapeProperties()
{
static tMakePropertyNameMap m_aShapePropertyMapForTextShapeProperties =
tMakePropertyNameMap
( PropertyMapper::getPropertyNameMapForCharacterProperties() )
( PropertyMapper::getPropertyNameMapForFillProperties() )
( PropertyMapper::getPropertyNameMapForLineProperties() );
return m_aShapePropertyMapForTextShapeProperties;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForLineSeriesProperties()
{
//shape property -- chart model object property
static tMakePropertyNameMap m_aShapePropertyMapForLineSeriesProperties =
tMakePropertyNameMap
( "LineColor", "Color" )
( "LineDashName", "LineDashName" )
( "LineStyle", "LineStyle" )
( "LineTransparence", "Transparency" )
( "LineWidth", "LineWidth" )
;
return m_aShapePropertyMapForLineSeriesProperties;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForTextLabelProperties()
{
// taget name (drawing layer) : source name (chart model)
static tMakePropertyNameMap aMap = tMakePropertyNameMap
( getPropertyNameMapForCharacterProperties() )
( "LineStyle", CHART_UNONAME_LABEL_BORDER_STYLE )
( "LineWidth", CHART_UNONAME_LABEL_BORDER_WIDTH )
( "LineColor", CHART_UNONAME_LABEL_BORDER_COLOR )
( "LineTransparence", CHART_UNONAME_LABEL_BORDER_TRANS ) // fix the spelling!
;
return aMap;
}
const tMakePropertyNameMap& PropertyMapper::getPropertyNameMapForFilledSeriesProperties()
{
//shape property -- chart model object property
static tMakePropertyNameMap m_aShapePropertyMapForFilledSeriesProperties =
tMakePropertyNameMap
( "FillBackground", "FillBackground" )
( "FillBitmapName", "FillBitmapName" )
( "FillColor", "Color" )
( "FillGradientName", "GradientName" )
( "FillGradientStepCount", "GradientStepCount" )
( "FillHatchName", "HatchName" )
( "FillStyle", "FillStyle" )
( "FillTransparence", "Transparency" )
( "FillTransparenceGradientName", "TransparencyGradientName" )
//bitmap properties
( "FillBitmapMode", "FillBitmapMode" )
( "FillBitmapSizeX", "FillBitmapSizeX" )
( "FillBitmapSizeY", "FillBitmapSizeY" )
( "FillBitmapLogicalSize", "FillBitmapLogicalSize" )
( "FillBitmapOffsetX", "FillBitmapOffsetX" )
( "FillBitmapOffsetY", "FillBitmapOffsetY" )
( "FillBitmapRectanglePoint", "FillBitmapRectanglePoint" )
( "FillBitmapPositionOffsetX", "FillBitmapPositionOffsetX" )
( "FillBitmapPositionOffsetY", "FillBitmapPositionOffsetY" )
//line properties
( "LineColor", "BorderColor" )
( "LineDashName", "BorderDashName" )
( "LineStyle", "BorderStyle" )
( "LineTransparence", "BorderTransparency" )
( "LineWidth", "BorderWidth" )
;
return m_aShapePropertyMapForFilledSeriesProperties;
}
void PropertyMapper::setMultiProperties(
const tNameSequence& rNames
, const tAnySequence& rValues
, const ::com::sun::star::uno::Reference<
::com::sun::star::beans::XPropertySet >& xTarget )
{
bool bSuccess = false;
try
{
uno::Reference< beans::XMultiPropertySet > xShapeMultiProp( xTarget, uno::UNO_QUERY );
if( xShapeMultiProp.is() )
{
xShapeMultiProp->setPropertyValues( rNames, rValues );
bSuccess = true;
}
}
catch( const uno::Exception& e )
{
ASSERT_EXCEPTION( e ); //if this occurs more often think of removing the XMultiPropertySet completely for better performance
}
if(!bSuccess)
try
{
sal_Int32 nCount = std::max( rNames.getLength(), rValues.getLength() );
OUString aPropName;
uno::Any aValue;
for( sal_Int32 nN = 0; nN < nCount; nN++ )
{
aPropName = rNames[nN];
aValue = rValues[nN];
try
{
xTarget->setPropertyValue( aPropName, aValue );
}
catch( const uno::Exception& e )
{
ASSERT_EXCEPTION( e );
}
}
}
catch( const uno::Exception& e )
{
ASSERT_EXCEPTION( e );
}
}
void PropertyMapper::getTextLabelMultiPropertyLists(
const uno::Reference< beans::XPropertySet >& xSourceProp
, tNameSequence& rPropNames, tAnySequence& rPropValues
, bool bName
, sal_Int32 nLimitedSpace
, bool bLimitedHeight )
{
//fill character properties into the ValueMap
tPropertyNameValueMap aValueMap;
tMakePropertyNameMap aNameMap = PropertyMapper::getPropertyNameMapForTextLabelProperties();
PropertyMapper::getValueMap(aValueMap, aNameMap, xSourceProp);
//some more shape properties apart from character properties, position-matrix and label string
aValueMap.insert( tPropertyNameValueMap::value_type( "TextHorizontalAdjust", uno::makeAny(drawing::TextHorizontalAdjust_CENTER) ) ); // drawing::TextHorizontalAdjust - needs to be overwritten
aValueMap.insert( tPropertyNameValueMap::value_type( "TextVerticalAdjust", uno::makeAny(drawing::TextVerticalAdjust_CENTER) ) ); //drawing::TextVerticalAdjust - needs to be overwritten
aValueMap.insert( tPropertyNameValueMap::value_type( "TextAutoGrowHeight", uno::makeAny(sal_True) ) ); // sal_Bool
aValueMap.insert( tPropertyNameValueMap::value_type( "TextAutoGrowWidth", uno::makeAny(sal_True) ) ); // sal_Bool
if( bName )
aValueMap.insert( tPropertyNameValueMap::value_type( "Name", uno::makeAny( OUString() ) ) ); //CID OUString - needs to be overwritten for each point
if( nLimitedSpace > 0 )
{
if(bLimitedHeight)
aValueMap.insert( tPropertyNameValueMap::value_type( "TextMaximumFrameHeight", uno::makeAny(nLimitedSpace) ) ); //sal_Int32
else
aValueMap.insert( tPropertyNameValueMap::value_type( "TextMaximumFrameWidth", uno::makeAny(nLimitedSpace) ) ); //sal_Int32
aValueMap.insert( tPropertyNameValueMap::value_type( "ParaIsHyphenation", uno::makeAny(sal_True) ) );
}
PropertyMapper::getMultiPropertyListsFromValueMap( rPropNames, rPropValues, aValueMap );
}
void PropertyMapper::getPreparedTextShapePropertyLists(
const uno::Reference< beans::XPropertySet >& xSourceProp
, tNameSequence& rPropNames, tAnySequence& rPropValues )
{
//fill character, line and fill properties into the ValueMap
tPropertyNameValueMap aValueMap;
PropertyMapper::getValueMap( aValueMap
, PropertyMapper::getPropertyNameMapForTextShapeProperties()
, xSourceProp );
// auto-grow makes sure the shape has the correct size after setting text
aValueMap.insert( tPropertyNameValueMap::value_type( "TextHorizontalAdjust", uno::makeAny( drawing::TextHorizontalAdjust_CENTER )));
aValueMap.insert( tPropertyNameValueMap::value_type( "TextVerticalAdjust", uno::makeAny( drawing::TextVerticalAdjust_CENTER )));
aValueMap.insert( tPropertyNameValueMap::value_type( "TextAutoGrowHeight", uno::makeAny( true )));
aValueMap.insert( tPropertyNameValueMap::value_type( "TextAutoGrowWidth", uno::makeAny( true )));
// set some distance to the border, in case it is shown
const sal_Int32 nWidthDist = 250;
const sal_Int32 nHeightDist = 125;
aValueMap.insert( tPropertyNameValueMap::value_type( "TextLeftDistance", uno::makeAny( nWidthDist )));
aValueMap.insert( tPropertyNameValueMap::value_type( "TextRightDistance", uno::makeAny( nWidthDist )));
aValueMap.insert( tPropertyNameValueMap::value_type( "TextUpperDistance", uno::makeAny( nHeightDist )));
aValueMap.insert( tPropertyNameValueMap::value_type( "TextLowerDistance", uno::makeAny( nHeightDist )));
// use a line-joint showing the border of thick lines like two rectangles
// filled in between.
aValueMap["LineJoint"] <<= drawing::LineJoint_ROUND;
PropertyMapper::getMultiPropertyListsFromValueMap( rPropNames, rPropValues, aValueMap );
}
} //namespace chart
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */