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