/* -*- 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 #include #include #include #include #include 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& 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() { // target 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: */