1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "oox/drawingml/shape.hxx" 25 #include "oox/drawingml/customshapeproperties.hxx" 26 #include "oox/drawingml/theme.hxx" 27 #include "oox/drawingml/fillproperties.hxx" 28 #include "oox/drawingml/lineproperties.hxx" 29 #include "oox/drawingml/shapepropertymap.hxx" 30 #include "oox/drawingml/textbody.hxx" 31 #include "oox/drawingml/table/tableproperties.hxx" 32 #include "oox/drawingml/chart/chartconverter.hxx" 33 #include "oox/drawingml/chart/chartspacefragment.hxx" 34 #include "oox/drawingml/chart/chartspacemodel.hxx" 35 #include "oox/vml/vmldrawing.hxx" 36 #include "oox/vml/vmlshape.hxx" 37 #include "oox/vml/vmlshapecontainer.hxx" 38 #include "oox/core/xmlfilterbase.hxx" 39 #include "oox/helper/graphichelper.hxx" 40 #include "oox/helper/propertyset.hxx" 41 42 #include <tools/solar.h> // for the F_PI180 define 43 #include <com/sun/star/graphic/XGraphic.hpp> 44 #include <com/sun/star/container/XNamed.hpp> 45 #include <com/sun/star/beans/XMultiPropertySet.hpp> 46 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 47 #include <com/sun/star/drawing/HomogenMatrix3.hpp> 48 #include <com/sun/star/text/XText.hpp> 49 #include <com/sun/star/chart2/XChartDocument.hpp> 50 #include <basegfx/point/b2dpoint.hxx> 51 #include <basegfx/polygon/b2dpolygon.hxx> 52 #include <basegfx/matrix/b2dhommatrix.hxx> 53 #include <com/sun/star/document/XActionLockable.hpp> 54 55 using rtl::OUString; 56 using namespace ::oox::core; 57 using namespace ::com::sun::star; 58 using namespace ::com::sun::star::awt; 59 using namespace ::com::sun::star::uno; 60 using namespace ::com::sun::star::beans; 61 using namespace ::com::sun::star::frame; 62 using namespace ::com::sun::star::text; 63 using namespace ::com::sun::star::drawing; 64 65 namespace oox { namespace drawingml { 66 67 // ============================================================================ 68 69 Shape::Shape( const sal_Char* pServiceName ) 70 : mpLinePropertiesPtr( new LineProperties ) 71 , mpFillPropertiesPtr( new FillProperties ) 72 , mpGraphicPropertiesPtr( new GraphicProperties ) 73 , mpCustomShapePropertiesPtr( new CustomShapeProperties ) 74 , mpMasterTextListStyle( new TextListStyle ) 75 , mnSubType( 0 ) 76 , mnSubTypeIndex( -1 ) 77 , meFrameType( FRAMETYPE_GENERIC ) 78 , mnRotation( 0 ) 79 , mbFlipH( false ) 80 , mbFlipV( false ) 81 , mbHidden( false ) 82 { 83 if ( pServiceName ) 84 msServiceName = OUString::createFromAscii( pServiceName ); 85 setDefaults(); 86 } 87 88 Shape::~Shape() 89 { 90 } 91 92 table::TablePropertiesPtr Shape::getTableProperties() 93 { 94 if ( !mpTablePropertiesPtr.get() ) 95 mpTablePropertiesPtr.reset( new table::TableProperties() ); 96 return mpTablePropertiesPtr; 97 } 98 99 void Shape::setDefaults() 100 { 101 maShapeProperties[ PROP_TextAutoGrowHeight ] <<= false; 102 maShapeProperties[ PROP_TextWordWrap ] <<= true; 103 maShapeProperties[ PROP_TextLeftDistance ] <<= static_cast< sal_Int32 >( 250 ); 104 maShapeProperties[ PROP_TextUpperDistance ] <<= static_cast< sal_Int32 >( 125 ); 105 maShapeProperties[ PROP_TextRightDistance ] <<= static_cast< sal_Int32 >( 250 ); 106 maShapeProperties[ PROP_TextLowerDistance ] <<= static_cast< sal_Int32 >( 125 ); 107 maShapeProperties[ PROP_CharHeight ] <<= static_cast< float >( 18.0 ); 108 } 109 110 ::oox::vml::OleObjectInfo& Shape::setOleObjectType() 111 { 112 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" ); 113 meFrameType = FRAMETYPE_OLEOBJECT; 114 mxOleObjectInfo.reset( new ::oox::vml::OleObjectInfo( true ) ); 115 return *mxOleObjectInfo; 116 } 117 118 ChartShapeInfo& Shape::setChartType( bool bEmbedShapes ) 119 { 120 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" ); 121 meFrameType = FRAMETYPE_CHART; 122 msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ); 123 mxChartShapeInfo.reset( new ChartShapeInfo( bEmbedShapes ) ); 124 return *mxChartShapeInfo; 125 } 126 127 void Shape::setDiagramType() 128 { 129 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" ); 130 meFrameType = FRAMETYPE_DIAGRAM; 131 msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ); 132 mnSubType = 0; 133 } 134 135 void Shape::setTableType() 136 { 137 OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" ); 138 meFrameType = FRAMETYPE_TABLE; 139 msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.TableShape" ); 140 mnSubType = 0; 141 } 142 143 void Shape::setServiceName( const sal_Char* pServiceName ) 144 { 145 if ( pServiceName ) 146 msServiceName = OUString::createFromAscii( pServiceName ); 147 } 148 149 150 const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const 151 { 152 ShapeStyleRefMap::const_iterator aIt = maShapeStyleRefs.find( nRefType ); 153 return (aIt == maShapeStyleRefs.end()) ? 0 : &aIt->second; 154 } 155 156 void Shape::addShape( 157 ::oox::core::XmlFilterBase& rFilterBase, 158 const Theme* pTheme, 159 const Reference< XShapes >& rxShapes, 160 const awt::Rectangle* pShapeRect, 161 ShapeIdMap* pShapeMap ) 162 { 163 try 164 { 165 rtl::OUString sServiceName( msServiceName ); 166 if( sServiceName.getLength() ) 167 { 168 Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, sal_False ) ); 169 170 if( pShapeMap && msId.getLength() ) 171 { 172 (*pShapeMap)[ msId ] = shared_from_this(); 173 } 174 175 // if this is a group shape, we have to add also each child shape 176 Reference< XShapes > xShapes( xShape, UNO_QUERY ); 177 if ( xShapes.is() ) 178 addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap ); 179 } 180 } 181 catch( const Exception& ) 182 { 183 } 184 } 185 186 void Shape::applyShapeReference( const Shape& rReferencedShape ) 187 { 188 mpTextBody = TextBodyPtr( new TextBody( *rReferencedShape.mpTextBody.get() ) ); 189 maShapeProperties = rReferencedShape.maShapeProperties; 190 mpLinePropertiesPtr = LinePropertiesPtr( new LineProperties( *rReferencedShape.mpLinePropertiesPtr.get() ) ); 191 mpFillPropertiesPtr = FillPropertiesPtr( new FillProperties( *rReferencedShape.mpFillPropertiesPtr.get() ) ); 192 mpCustomShapePropertiesPtr = CustomShapePropertiesPtr( new CustomShapeProperties( *rReferencedShape.mpCustomShapePropertiesPtr.get() ) ); 193 mpTablePropertiesPtr = table::TablePropertiesPtr( rReferencedShape.mpTablePropertiesPtr.get() ? new table::TableProperties( *rReferencedShape.mpTablePropertiesPtr.get() ) : NULL ); 194 mpMasterTextListStyle = TextListStylePtr( new TextListStyle( *rReferencedShape.mpMasterTextListStyle.get() ) ); 195 maShapeStyleRefs = rReferencedShape.maShapeStyleRefs; 196 maSize = rReferencedShape.maSize; 197 maPosition = rReferencedShape.maPosition; 198 mnRotation = rReferencedShape.mnRotation; 199 mbFlipH = rReferencedShape.mbFlipH; 200 mbFlipV = rReferencedShape.mbFlipV; 201 mbHidden = rReferencedShape.mbHidden; 202 } 203 204 // for group shapes, the following method is also adding each child 205 void Shape::addChildren( 206 XmlFilterBase& rFilterBase, 207 Shape& rMaster, 208 const Theme* pTheme, 209 const Reference< XShapes >& rxShapes, 210 const awt::Rectangle& rClientRect, 211 ShapeIdMap* pShapeMap ) 212 { 213 // first the global child union needs to be calculated 214 sal_Int32 nGlobalLeft = SAL_MAX_INT32; 215 sal_Int32 nGlobalRight = SAL_MIN_INT32; 216 sal_Int32 nGlobalTop = SAL_MAX_INT32; 217 sal_Int32 nGlobalBottom= SAL_MIN_INT32; 218 std::vector< ShapePtr >::iterator aIter( rMaster.maChildren.begin() ); 219 while( aIter != rMaster.maChildren.end() ) 220 { 221 sal_Int32 l = (*aIter)->maPosition.X; 222 sal_Int32 t = (*aIter)->maPosition.Y; 223 sal_Int32 r = l + (*aIter)->maSize.Width; 224 sal_Int32 b = t + (*aIter)->maSize.Height; 225 if ( nGlobalLeft > l ) 226 nGlobalLeft = l; 227 if ( nGlobalRight < r ) 228 nGlobalRight = r; 229 if ( nGlobalTop > t ) 230 nGlobalTop = t; 231 if ( nGlobalBottom < b ) 232 nGlobalBottom = b; 233 aIter++; 234 } 235 aIter = rMaster.maChildren.begin(); 236 while( aIter != rMaster.maChildren.end() ) 237 { 238 awt::Rectangle aShapeRect; 239 awt::Rectangle* pShapeRect = 0; 240 if ( ( nGlobalLeft != SAL_MAX_INT32 ) && ( nGlobalRight != SAL_MIN_INT32 ) && ( nGlobalTop != SAL_MAX_INT32 ) && ( nGlobalBottom != SAL_MIN_INT32 ) ) 241 { 242 sal_Int32 nGlobalWidth = nGlobalRight - nGlobalLeft; 243 sal_Int32 nGlobalHeight = nGlobalBottom - nGlobalTop; 244 if ( nGlobalWidth && nGlobalHeight ) 245 { 246 double fWidth = (*aIter)->maSize.Width; 247 double fHeight= (*aIter)->maSize.Height; 248 double fXScale = (double)rClientRect.Width / (double)nGlobalWidth; 249 double fYScale = (double)rClientRect.Height / (double)nGlobalHeight; 250 aShapeRect.X = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.X - nGlobalLeft ) * fXScale ) + rClientRect.X ); 251 aShapeRect.Y = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.Y - nGlobalTop ) * fYScale ) + rClientRect.Y ); 252 fWidth *= fXScale; 253 fHeight *= fYScale; 254 aShapeRect.Width = static_cast< sal_Int32 >( fWidth ); 255 aShapeRect.Height = static_cast< sal_Int32 >( fHeight ); 256 pShapeRect = &aShapeRect; 257 } 258 } 259 (*aIter++)->addShape( rFilterBase, pTheme, rxShapes, pShapeRect, pShapeMap ); 260 } 261 } 262 263 Reference< XShape > Shape::createAndInsert( 264 ::oox::core::XmlFilterBase& rFilterBase, 265 const rtl::OUString& rServiceName, 266 const Theme* pTheme, 267 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, 268 const awt::Rectangle* pShapeRect, 269 sal_Bool bClearText ) 270 { 271 awt::Size aSize( pShapeRect ? awt::Size( pShapeRect->Width, pShapeRect->Height ) : maSize ); 272 awt::Point aPosition( pShapeRect ? awt::Point( pShapeRect->X, pShapeRect->Y ) : maPosition ); 273 awt::Rectangle aShapeRectHmm( aPosition.X / 360, aPosition.Y / 360, aSize.Width / 360, aSize.Height / 360 ); 274 275 OUString aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm ); 276 sal_Bool bIsCustomShape = aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShape" ) ); 277 278 basegfx::B2DHomMatrix aTransformation; 279 if( aSize.Width != 1 || aSize.Height != 1) 280 { 281 // take care there are no zeros used by error 282 aTransformation.scale( 283 aSize.Width ? aSize.Width / 360.0 : 1.0, 284 aSize.Height ? aSize.Height / 360.0 : 1.0 ); 285 } 286 287 if( mbFlipH || mbFlipV || mnRotation != 0) 288 { 289 // calculate object's center 290 basegfx::B2DPoint aCenter(0.5, 0.5); 291 aCenter *= aTransformation; 292 293 // center object at origin 294 aTransformation.translate( -aCenter.getX(), -aCenter.getY() ); 295 296 if( !bIsCustomShape && ( mbFlipH || mbFlipV ) ) 297 { 298 // mirror around object's center 299 aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 ); 300 } 301 302 if( mnRotation != 0 ) 303 { 304 // rotate around object's center 305 aTransformation.rotate( F_PI180 * ( (double)mnRotation / 60000.0 ) ); 306 } 307 308 // move object back from center 309 aTransformation.translate( aCenter.getX(), aCenter.getY() ); 310 } 311 312 if( aPosition.X != 0 || aPosition.Y != 0) 313 { 314 // if global position is used, add it to transformation 315 aTransformation.translate( aPosition.X / 360.0, aPosition.Y / 360.0 ); 316 } 317 318 // special for lineshape 319 if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.LineShape" ) ) 320 { 321 ::basegfx::B2DPolygon aPoly; 322 aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) ); 323 aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) ); 324 aPoly.transform( aTransformation ); 325 326 // now creating the corresponding PolyPolygon 327 sal_Int32 i, nNumPoints = aPoly.count(); 328 uno::Sequence< awt::Point > aPointSequence( nNumPoints ); 329 awt::Point* pPoints = aPointSequence.getArray(); 330 for( i = 0; i < nNumPoints; ++i ) 331 { 332 const ::basegfx::B2DPoint aPoint( aPoly.getB2DPoint( i ) ); 333 pPoints[ i ] = awt::Point( static_cast< sal_Int32 >( aPoint.getX() ), static_cast< sal_Int32 >( aPoint.getY() ) ); 334 } 335 uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 ); 336 aPolyPolySequence.getArray()[ 0 ] = aPointSequence; 337 338 maShapeProperties[ PROP_PolyPolygon ] <<= aPolyPolySequence; 339 } 340 else if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.ConnectorShape" ) ) 341 { 342 ::basegfx::B2DPolygon aPoly; 343 aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) ); 344 aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) ); 345 aPoly.transform( aTransformation ); 346 347 basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) ); 348 basegfx::B2DPoint aEndPosition( aPoly.getB2DPoint( 1 ) ); 349 awt::Point aAWTStartPosition( static_cast< sal_Int32 >( aStartPosition.getX() ), static_cast< sal_Int32 >( aStartPosition.getY() ) ); 350 awt::Point aAWTEndPosition( static_cast< sal_Int32 >( aEndPosition.getX() ), static_cast< sal_Int32 >( aEndPosition.getY() ) ); 351 352 maShapeProperties[ PROP_StartPosition ] <<= aAWTStartPosition; 353 maShapeProperties[ PROP_EndPosition ] <<= aAWTEndPosition; 354 } 355 else 356 { 357 // now set transformation for this object 358 HomogenMatrix3 aMatrix; 359 360 aMatrix.Line1.Column1 = aTransformation.get(0,0); 361 aMatrix.Line1.Column2 = aTransformation.get(0,1); 362 aMatrix.Line1.Column3 = aTransformation.get(0,2); 363 364 aMatrix.Line2.Column1 = aTransformation.get(1,0); 365 aMatrix.Line2.Column2 = aTransformation.get(1,1); 366 aMatrix.Line2.Column3 = aTransformation.get(1,2); 367 368 aMatrix.Line3.Column1 = aTransformation.get(2,0); 369 aMatrix.Line3.Column2 = aTransformation.get(2,1); 370 aMatrix.Line3.Column3 = aTransformation.get(2,2); 371 372 maShapeProperties[ PROP_Transformation ] <<= aMatrix; 373 } 374 Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW ); 375 if ( !mxShape.is() ) 376 mxShape = Reference< drawing::XShape >( xServiceFact->createInstance( aServiceName ), UNO_QUERY_THROW ); 377 378 Reference< XPropertySet > xSet( mxShape, UNO_QUERY ); 379 if( mxShape.is() && xSet.is() ) 380 { 381 if( msName.getLength() ) 382 { 383 Reference< container::XNamed > xNamed( mxShape, UNO_QUERY ); 384 if( xNamed.is() ) 385 xNamed->setName( msName ); 386 } 387 rxShapes->add( mxShape ); 388 389 if ( mbHidden ) 390 { 391 const OUString sHidden( CREATE_OUSTRING( "Visible" ) ); 392 xSet->setPropertyValue( sHidden, Any( !mbHidden ) ); 393 } 394 395 Reference< document::XActionLockable > xLockable( mxShape, UNO_QUERY ); 396 if( xLockable.is() ) 397 xLockable->addActionLock(); 398 399 // sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape 400 if ( bClearText ) 401 { 402 uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY ); 403 if ( xText.is() ) 404 { 405 OUString aEmpty; 406 xText->setString( aEmpty ); 407 } 408 } 409 410 const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper(); 411 412 LineProperties aLineProperties; 413 aLineProperties.maLineFill.moFillType = XML_noFill; 414 sal_Int32 nLinePhClr = -1; 415 FillProperties aFillProperties; 416 aFillProperties.moFillType = XML_noFill; 417 sal_Int32 nFillPhClr = -1; 418 419 if( pTheme ) 420 { 421 if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) ) 422 { 423 if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) ) 424 aLineProperties.assignUsed( *pLineProps ); 425 nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper ); 426 } 427 if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) ) 428 { 429 if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) ) 430 aFillProperties.assignUsed( *pFillProps ); 431 nFillPhClr = pFillRef->maPhClr.getColor( rGraphicHelper ); 432 } 433 // if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_fillRef ) ) 434 // { 435 // if( const EffectProperties* pEffectProps = pTheme->getEffectStyle( pEffectRef->mnThemedIdx ) ) 436 // aEffectProperties.assignUsed( *pEffectProps ); 437 // nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper ); 438 // } 439 } 440 441 aLineProperties.assignUsed( getLineProperties() ); 442 aFillProperties.assignUsed( getFillProperties() ); 443 444 ShapePropertyMap aShapeProps( rFilterBase.getModelObjectHelper() ); 445 446 // add properties from textbody to shape properties 447 if( mpTextBody.get() ) 448 aShapeProps.assignUsed( mpTextBody->getTextProperties().maPropertyMap ); 449 450 // applying properties 451 aShapeProps.assignUsed( getShapeProperties() ); 452 if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) ) 453 mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, rGraphicHelper ); 454 if ( mpTablePropertiesPtr.get() && ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.TableShape" ) ) ) 455 mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle ); 456 aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr ); 457 aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr ); 458 459 // applying autogrowheight property before setting shape size, because 460 // the shape size might be changed if currently autogrowheight is true 461 // we must also check that the PropertySet supports the property. 462 Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() ); 463 const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight ); 464 if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) ) 465 if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) ) 466 xSet->setPropertyValue( rPropName, Any( false ) ); 467 468 // do not set properties at a group shape (this causes assertions from svx) 469 if( aServiceName != OUString::createFromAscii( "com.sun.star.drawing.GroupShape" ) ) 470 PropertySet( xSet ).setProperties( aShapeProps ); 471 472 if( bIsCustomShape ) 473 { 474 if ( mbFlipH ) 475 mpCustomShapePropertiesPtr->setMirroredX( sal_True ); 476 if ( mbFlipV ) 477 mpCustomShapePropertiesPtr->setMirroredY( sal_True ); 478 479 // #119920 Handle missing text rotation 480 if(getTextBody()) 481 { 482 const sal_Int32 nTextRotation(getTextBody()->getTextProperties().moRotation.get(0)); 483 484 if(nTextRotation) 485 { 486 mpCustomShapePropertiesPtr->setTextRotation((nTextRotation * -1) / 60000); 487 } 488 } 489 490 mpCustomShapePropertiesPtr->pushToPropSet( rFilterBase, xSet, mxShape ); 491 } 492 493 // in some cases, we don't have any text body. 494 if( getTextBody() ) 495 { 496 Reference < XText > xText( mxShape, UNO_QUERY ); 497 if ( xText.is() ) // not every shape is supporting an XText interface (e.g. GroupShape) 498 { 499 TextCharacterProperties aCharStyleProperties; 500 if( const ShapeStyleRef* pFontRef = getShapeStyleRef( XML_fontRef ) ) 501 { 502 if( pTheme ) 503 if( const TextCharacterProperties* pCharProps = pTheme->getFontStyle( pFontRef->mnThemedIdx ) ) 504 aCharStyleProperties.assignUsed( *pCharProps ); 505 aCharStyleProperties.maCharColor.assignIfUsed( pFontRef->maPhClr ); 506 } 507 508 Reference < XTextCursor > xAt = xText->createTextCursor(); 509 getTextBody()->insertAt( rFilterBase, xText, xAt, aCharStyleProperties, mpMasterTextListStyle ); 510 } 511 } 512 if( xLockable.is() ) 513 xLockable->removeActionLock(); 514 } 515 516 if( mxShape.is() ) 517 finalizeXShape( rFilterBase, rxShapes ); 518 519 return mxShape; 520 } 521 522 // the properties of rSource which are not part of rDest are being put into rDest 523 void addMissingProperties( const PropertyMap& rSource, PropertyMap& rDest ) 524 { 525 PropertyMap::const_iterator aSourceIter( rSource.begin() ); 526 while( aSourceIter != rSource.end() ) 527 { 528 if ( rDest.find( (*aSourceIter ).first ) == rDest.end() ) 529 rDest[ (*aSourceIter).first ] <<= (*aSourceIter).second; 530 aSourceIter++; 531 } 532 } 533 534 void Shape::setTextBody(const TextBodyPtr & pTextBody) 535 { 536 mpTextBody = pTextBody; 537 } 538 539 540 TextBodyPtr Shape::getTextBody() 541 { 542 return mpTextBody; 543 } 544 545 void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle ) 546 { 547 mpMasterTextListStyle = pMasterTextListStyle; 548 } 549 550 OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const Rectangle& rShapeRect ) 551 { 552 OUString aServiceName = rServiceName; 553 switch( meFrameType ) 554 { 555 case FRAMETYPE_OLEOBJECT: 556 { 557 Size aOleSize( rShapeRect.Width, rShapeRect.Height ); 558 if( rFilter.getOleObjectHelper().importOleObject( maShapeProperties, *mxOleObjectInfo, aOleSize ) ) 559 aServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ); 560 561 // get the path to the representation graphic 562 OUString aGraphicPath; 563 if( mxOleObjectInfo->maShapeId.getLength() > 0 ) 564 if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() ) 565 if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) ) 566 aGraphicPath = pVmlShape->getGraphicPath(); 567 568 // import and store the graphic 569 if( aGraphicPath.getLength() > 0 ) 570 { 571 Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath ); 572 if( xGraphic.is() ) 573 maShapeProperties[ PROP_Graphic ] <<= xGraphic; 574 } 575 } 576 break; 577 578 default:; 579 } 580 return aServiceName; 581 } 582 583 void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes ) 584 { 585 switch( meFrameType ) 586 { 587 case FRAMETYPE_CHART: 588 { 589 OSL_ENSURE( mxChartShapeInfo->maFragmentPath.getLength() > 0, "Shape::finalizeXShape - missing chart fragment" ); 590 if( mxShape.is() && (mxChartShapeInfo->maFragmentPath.getLength() > 0) ) try 591 { 592 // set the chart2 OLE class ID at the OLE shape 593 PropertySet aShapeProp( mxShape ); 594 aShapeProp.setProperty( PROP_CLSID, CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) ); 595 596 // get the XModel interface of the embedded object from the OLE shape 597 Reference< frame::XModel > xDocModel; 598 aShapeProp.getProperty( xDocModel, PROP_Model ); 599 Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW ); 600 601 // load the chart data from the XML fragment 602 chart::ChartSpaceModel aModel; 603 rFilter.importFragment( new chart::ChartSpaceFragment( rFilter, mxChartShapeInfo->maFragmentPath, aModel ) ); 604 605 // convert imported chart model to chart document 606 Reference< drawing::XShapes > xExternalPage; 607 if( !mxChartShapeInfo->mbEmbedShapes ) 608 xExternalPage = rxShapes; 609 rFilter.getChartConverter().convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() ); 610 } 611 catch( Exception& ) 612 { 613 } 614 } 615 break; 616 617 default:; 618 } 619 } 620 621 // ============================================================================ 622 623 } } 624