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