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