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