xref: /trunk/main/oox/source/drawingml/shape.cxx (revision cdf0e10c)
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