1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "oox/drawingml/customshapeproperties.hxx" 29*cdf0e10cSrcweir #include "oox/helper/helper.hxx" 30*cdf0e10cSrcweir #include "oox/helper/propertymap.hxx" 31*cdf0e10cSrcweir #include "oox/helper/propertyset.hxx" 32*cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/beans/XMultiPropertySet.hpp> 34*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/graphic/XGraphicTransformer.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/drawing/XShape.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp> 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir using rtl::OUString; 40*cdf0e10cSrcweir using namespace ::oox::core; 41*cdf0e10cSrcweir using namespace ::com::sun::star; 42*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 43*cdf0e10cSrcweir using namespace ::com::sun::star::beans; 44*cdf0e10cSrcweir using namespace ::com::sun::star::graphic; 45*cdf0e10cSrcweir using namespace ::com::sun::star::drawing; 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir namespace oox { namespace drawingml { 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir CustomShapeProperties::CustomShapeProperties() 50*cdf0e10cSrcweir : mbMirroredX ( sal_False ) 51*cdf0e10cSrcweir , mbMirroredY ( sal_False ) 52*cdf0e10cSrcweir { 53*cdf0e10cSrcweir } 54*cdf0e10cSrcweir CustomShapeProperties::~CustomShapeProperties() 55*cdf0e10cSrcweir { 56*cdf0e10cSrcweir } 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir sal_Int32 CustomShapeProperties::SetCustomShapeGuideValue( std::vector< CustomShapeGuide >& rGuideList, const CustomShapeGuide& rGuide ) 59*cdf0e10cSrcweir { 60*cdf0e10cSrcweir sal_uInt32 nIndex = 0; 61*cdf0e10cSrcweir for( ; nIndex < rGuideList.size(); nIndex++ ) 62*cdf0e10cSrcweir { 63*cdf0e10cSrcweir if ( rGuideList[ nIndex ].maName == rGuide.maName ) 64*cdf0e10cSrcweir break; 65*cdf0e10cSrcweir } 66*cdf0e10cSrcweir if ( nIndex == rGuideList.size() ) 67*cdf0e10cSrcweir rGuideList.push_back( rGuide ); 68*cdf0e10cSrcweir return static_cast< sal_Int32 >( nIndex ); 69*cdf0e10cSrcweir } 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir // returns the index into the guidelist for a given formula name, 72*cdf0e10cSrcweir // if the return value is < 0 then the guide value could not be found 73*cdf0e10cSrcweir sal_Int32 CustomShapeProperties::GetCustomShapeGuideValue( const std::vector< CustomShapeGuide >& rGuideList, const rtl::OUString& rFormulaName ) 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir sal_Int32 nIndex = 0; 76*cdf0e10cSrcweir for( ; nIndex < static_cast< sal_Int32 >( rGuideList.size() ); nIndex++ ) 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir if ( rGuideList[ nIndex ].maName == rFormulaName ) 79*cdf0e10cSrcweir break; 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir if ( nIndex == static_cast< sal_Int32 >( rGuideList.size() ) ) 82*cdf0e10cSrcweir nIndex = -1; 83*cdf0e10cSrcweir return nIndex; 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir void CustomShapeProperties::apply( const CustomShapePropertiesPtr& /* rSourceCustomShapeProperties */ ) 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir // not sure if this needs to be implemented 89*cdf0e10cSrcweir } 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir void CustomShapeProperties::pushToPropSet( const ::oox::core::FilterBase& /* rFilterBase */, 92*cdf0e10cSrcweir const Reference < XPropertySet >& xPropSet, const Reference < XShape > & xShape ) const 93*cdf0e10cSrcweir { 94*cdf0e10cSrcweir if ( maShapePresetType.getLength() ) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir //const uno::Reference < drawing::XShape > xShape( xPropSet, UNO_QUERY ); 97*cdf0e10cSrcweir Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY ); 98*cdf0e10cSrcweir if( xDefaulter.is() ) 99*cdf0e10cSrcweir xDefaulter->createCustomShapeDefaults( maShapePresetType ); 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir if ( maAdjustmentGuideList.size() ) 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir const OUString sType = CREATE_OUSTRING( "Type" ); 104*cdf0e10cSrcweir const OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) ); 105*cdf0e10cSrcweir uno::Any aGeoPropSet = xPropSet->getPropertyValue( sCustomShapeGeometry ); 106*cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aGeoPropSeq; 107*cdf0e10cSrcweir if ( aGeoPropSet >>= aGeoPropSeq ) 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir sal_Int32 i, nCount = aGeoPropSeq.getLength(); 110*cdf0e10cSrcweir for ( i = 0; i < nCount; i++ ) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM( "AdjustmentValues" ) ); 113*cdf0e10cSrcweir if ( aGeoPropSeq[ i ].Name.equals( sAdjustmentValues ) ) 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq; 116*cdf0e10cSrcweir if ( aGeoPropSeq[ i ].Value >>= aAdjustmentSeq ) 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir std::vector< CustomShapeGuide >::const_iterator aIter( maAdjustmentGuideList.begin() ); 119*cdf0e10cSrcweir while( aIter != maAdjustmentGuideList.end() ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir if ( (*aIter).maName.getLength() > 3 ) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir sal_Int32 nAdjustmentIndex = (*aIter).maName.copy( 3 ).toInt32() - 1; 124*cdf0e10cSrcweir if ( ( nAdjustmentIndex >= 0 ) && ( nAdjustmentIndex < aAdjustmentSeq.getLength() ) ) 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir EnhancedCustomShapeAdjustmentValue aAdjustmentVal; 127*cdf0e10cSrcweir aAdjustmentVal.Value <<= (*aIter).maFormula.toInt32(); 128*cdf0e10cSrcweir aAdjustmentVal.State = PropertyState_DIRECT_VALUE; 129*cdf0e10cSrcweir aAdjustmentSeq[ nAdjustmentIndex ] = aAdjustmentVal; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir aIter++; 133*cdf0e10cSrcweir } 134*cdf0e10cSrcweir aGeoPropSeq[ i ].Value <<= aAdjustmentSeq; 135*cdf0e10cSrcweir xPropSet->setPropertyValue( sCustomShapeGeometry, Any( aGeoPropSeq ) ); 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir else if ( aGeoPropSeq[ i ].Name.equals( sType ) ) 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir aGeoPropSeq[ i ].Value <<= maShapePresetType; 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir else 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir sal_uInt32 i; 149*cdf0e10cSrcweir PropertyMap aPropertyMap; 150*cdf0e10cSrcweir aPropertyMap[ PROP_Type ] <<= CREATE_OUSTRING( "non-primitive" ); 151*cdf0e10cSrcweir aPropertyMap[ PROP_MirroredX ] <<= Any( mbMirroredX ); 152*cdf0e10cSrcweir aPropertyMap[ PROP_MirroredY ] <<= Any( mbMirroredY ); 153*cdf0e10cSrcweir awt::Size aSize( xShape->getSize() ); 154*cdf0e10cSrcweir awt::Rectangle aViewBox( 0, 0, aSize.Width * 360, aSize.Height * 360 ); 155*cdf0e10cSrcweir if ( maPath2DList.size() ) 156*cdf0e10cSrcweir { // TODO: each polygon may have its own size, but I think it is rather been used 157*cdf0e10cSrcweir // so we are only taking care of the first 158*cdf0e10cSrcweir if ( maPath2DList[ 0 ].w ) 159*cdf0e10cSrcweir aViewBox.Width = static_cast< sal_Int32 >( maPath2DList[ 0 ].w ); 160*cdf0e10cSrcweir if ( maPath2DList[ 0 ].h ) 161*cdf0e10cSrcweir aViewBox.Height = static_cast< sal_Int32 >( maPath2DList[ 0 ].h ); 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir aPropertyMap[ PROP_ViewBox ] <<= aViewBox; 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir Sequence< EnhancedCustomShapeAdjustmentValue > aAdjustmentValues( maAdjustmentGuideList.size() ); 166*cdf0e10cSrcweir for ( i = 0; i < maAdjustmentGuideList.size(); i++ ) 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir EnhancedCustomShapeAdjustmentValue aAdjustmentVal; 169*cdf0e10cSrcweir aAdjustmentVal.Value <<= maAdjustmentGuideList[ i ].maFormula.toInt32(); 170*cdf0e10cSrcweir aAdjustmentVal.State = PropertyState_DIRECT_VALUE; 171*cdf0e10cSrcweir aAdjustmentValues[ i ] = aAdjustmentVal; 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir aPropertyMap[ PROP_AdjustmentValues ] <<= aAdjustmentValues; 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir Sequence< rtl::OUString > aEquations( maGuideList.size() ); 176*cdf0e10cSrcweir for ( i = 0; i < maGuideList.size(); i++ ) 177*cdf0e10cSrcweir aEquations[ i ] = maGuideList[ i ].maFormula; 178*cdf0e10cSrcweir aPropertyMap[ PROP_Equations ] <<= aEquations; 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir PropertyMap aPath; 181*cdf0e10cSrcweir Sequence< EnhancedCustomShapeSegment > aSegments( maSegments.size() ); 182*cdf0e10cSrcweir for ( i = 0; i < maSegments.size(); i++ ) 183*cdf0e10cSrcweir aSegments[ i ] = maSegments[ i ]; 184*cdf0e10cSrcweir aPath[ PROP_Segments ] <<= aSegments; 185*cdf0e10cSrcweir sal_uInt32 j, k, nParameterPairs = 0; 186*cdf0e10cSrcweir for ( i = 0; i < maPath2DList.size(); i++ ) 187*cdf0e10cSrcweir nParameterPairs += maPath2DList[ i ].parameter.size(); 188*cdf0e10cSrcweir Sequence< EnhancedCustomShapeParameterPair > aParameterPairs( nParameterPairs ); 189*cdf0e10cSrcweir for ( i = 0, k = 0; i < maPath2DList.size(); i++ ) 190*cdf0e10cSrcweir for ( j = 0; j < maPath2DList[ i ].parameter.size(); j++ ) 191*cdf0e10cSrcweir aParameterPairs[ k++ ] = maPath2DList[ i ].parameter[ j ]; 192*cdf0e10cSrcweir aPath[ PROP_Coordinates ] <<= aParameterPairs; 193*cdf0e10cSrcweir Sequence< PropertyValue > aPathSequence = aPath.makePropertyValueSequence(); 194*cdf0e10cSrcweir aPropertyMap[ PROP_Path ] <<= aPathSequence; 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir Sequence< PropertyValues > aHandles( maAdjustHandleList.size() ); 197*cdf0e10cSrcweir for ( i = 0; i < maAdjustHandleList.size(); i++ ) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir PropertyMap aHandle; 200*cdf0e10cSrcweir // maAdjustmentHandle[ i ].gdRef1 ... maAdjustmentHandle[ i ].gdRef2 ... :( 201*cdf0e10cSrcweir // gdRef1 && gdRef2 -> we do not offer such reference, so it is difficult 202*cdf0e10cSrcweir // to determine the correct adjustment handle that should be updated with the adjustment 203*cdf0e10cSrcweir // position. here is the solution: the adjustment value that is used within the position 204*cdf0e10cSrcweir // has to be updated, in case the position is a formula the first usage of a 205*cdf0e10cSrcweir // adjument value is decisive 206*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].polar ) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir aHandle[ PROP_Position ] <<= maAdjustHandleList[ i ].pos; 209*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].min1.has() ) 210*cdf0e10cSrcweir aHandle[ PROP_RadiusRangeMinimum ] <<= maAdjustHandleList[ i ].min1.get(); 211*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].max1.has() ) 212*cdf0e10cSrcweir aHandle[ PROP_RadiusRangeMaximum ] <<= maAdjustHandleList[ i ].max1.get(); 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir /* TODO: AngleMin & AngleMax 215*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].min2.has() ) 216*cdf0e10cSrcweir aHandle[ PROP_ ] = maAdjustHandleList[ i ].min2.get(); 217*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].max2.has() ) 218*cdf0e10cSrcweir aHandle[ PROP_ ] = maAdjustHandleList[ i ].max2.get(); 219*cdf0e10cSrcweir */ 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir else 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir aHandle[ PROP_Position ] <<= maAdjustHandleList[ i ].pos; 224*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].gdRef1.has() ) 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir // TODO: PROP_RefX and PROP_RefY are not yet part of our file format, 227*cdf0e10cSrcweir // so the handles will not work after save/reload 228*cdf0e10cSrcweir sal_Int32 nIndex = GetCustomShapeGuideValue( maAdjustmentGuideList, maAdjustHandleList[ i ].gdRef1.get() ); 229*cdf0e10cSrcweir if ( nIndex >= 0 ) 230*cdf0e10cSrcweir aHandle[ PROP_RefX ] <<= nIndex; 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].gdRef2.has() ) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir sal_Int32 nIndex = GetCustomShapeGuideValue( maAdjustmentGuideList, maAdjustHandleList[ i ].gdRef2.get() ); 235*cdf0e10cSrcweir if ( nIndex >= 0 ) 236*cdf0e10cSrcweir aHandle[ PROP_RefY ] <<= nIndex; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].min1.has() ) 239*cdf0e10cSrcweir aHandle[ PROP_RangeXMinimum ] <<= maAdjustHandleList[ i ].min1.get(); 240*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].max1.has() ) 241*cdf0e10cSrcweir aHandle[ PROP_RangeXMaximum ] <<= maAdjustHandleList[ i ].max1.get(); 242*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].min2.has() ) 243*cdf0e10cSrcweir aHandle[ PROP_RangeYMinimum ] <<= maAdjustHandleList[ i ].min2.get(); 244*cdf0e10cSrcweir if ( maAdjustHandleList[ i ].max2.has() ) 245*cdf0e10cSrcweir aHandle[ PROP_RangeYMaximum ] <<= maAdjustHandleList[ i ].max2.get(); 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir aHandles[ i ] = aHandle.makePropertyValueSequence(); 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir aPropertyMap[ PROP_Handles ] <<= aHandles; 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir // converting the vector to a sequence 252*cdf0e10cSrcweir Sequence< PropertyValue > aSeq = aPropertyMap.makePropertyValueSequence(); 253*cdf0e10cSrcweir PropertySet aPropSet( xPropSet ); 254*cdf0e10cSrcweir aPropSet.setProperty( PROP_CustomShapeGeometry, aSeq ); 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir double CustomShapeProperties::getValue( const std::vector< CustomShapeGuide >& rGuideList, sal_uInt32 nIndex ) const 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir double fRet = 0.0; 261*cdf0e10cSrcweir if ( nIndex < rGuideList.size() ) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir return fRet; 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir } } 269