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