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