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/vml/vmlshape.hxx"
25
26 #include <com/sun/star/beans/PropertyValues.hpp>
27 #include <com/sun/star/awt/XControlModel.hpp>
28 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
29 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
30 #include <com/sun/star/drawing/XShapes.hpp>
31 #include <com/sun/star/graphic/XGraphic.hpp>
32 #include <rtl/math.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include "oox/core/xmlfilterbase.hxx"
35 #include "oox/drawingml/shapepropertymap.hxx"
36 #include "oox/helper/containerhelper.hxx"
37 #include "oox/helper/graphichelper.hxx"
38 #include "oox/helper/propertyset.hxx"
39 #include "oox/ole/axcontrol.hxx"
40 #include "oox/ole/axcontrolfragment.hxx"
41 #include "oox/ole/oleobjecthelper.hxx"
42 #include "oox/vml/vmldrawing.hxx"
43 #include "oox/vml/vmlshapecontainer.hxx"
44 #include "oox/vml/vmltextbox.hxx"
45
46 namespace oox {
47 namespace vml {
48
49 // ============================================================================
50
51 using namespace ::com::sun::star::awt;
52 using namespace ::com::sun::star::drawing;
53 using namespace ::com::sun::star::graphic;
54 using namespace ::com::sun::star::uno;
55
56 using ::oox::core::XmlFilterBase;
57 using ::rtl::OUString;
58 using ::rtl::OUStringBuffer;
59
60 // ============================================================================
61
62 namespace {
63
64 const sal_Int32 VML_SHAPETYPE_PICTUREFRAME = 75;
65 const sal_Int32 VML_SHAPETYPE_HOSTCONTROL = 201;
66
67 // ----------------------------------------------------------------------------
68
lclGetAbsPoint(const Point & rRelPoint,const Rectangle & rShapeRect,const Rectangle & rCoordSys)69 Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
70 {
71 double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
72 double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
73 Point aAbsPoint;
74 aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
75 aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
76 return aAbsPoint;
77 }
78
lclGetAbsRect(const Rectangle & rRelRect,const Rectangle & rShapeRect,const Rectangle & rCoordSys)79 Rectangle lclGetAbsRect( const Rectangle& rRelRect, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
80 {
81 double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
82 double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
83 Rectangle aAbsRect;
84 aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
85 aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
86 aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
87 aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
88 return aAbsRect;
89 }
90
91 } // namespace
92
93 // ============================================================================
94
ShapeTypeModel()95 ShapeTypeModel::ShapeTypeModel()
96 {
97 }
98
assignUsed(const ShapeTypeModel & rSource)99 void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
100 {
101 moShapeType.assignIfUsed( rSource.moShapeType );
102 moCoordPos.assignIfUsed( rSource.moCoordPos );
103 moCoordSize.assignIfUsed( rSource.moCoordSize );
104 /* The style properties position, left, top, width, height, margin-left,
105 margin-top are not derived from shape template to shape. */
106 maStrokeModel.assignUsed( rSource.maStrokeModel );
107 maFillModel.assignUsed( rSource.maFillModel );
108 moGraphicPath.assignIfUsed( rSource.moGraphicPath );
109 moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
110 }
111
112 // ----------------------------------------------------------------------------
113
ShapeType(Drawing & rDrawing)114 ShapeType::ShapeType( Drawing& rDrawing ) :
115 mrDrawing( rDrawing )
116 {
117 }
118
~ShapeType()119 ShapeType::~ShapeType()
120 {
121 }
122
getShapeType() const123 sal_Int32 ShapeType::getShapeType() const
124 {
125 return maTypeModel.moShapeType.get( 0 );
126 }
127
getGraphicPath() const128 OUString ShapeType::getGraphicPath() const
129 {
130 return maTypeModel.moGraphicPath.get( OUString() );
131 }
132
getCoordSystem() const133 Rectangle ShapeType::getCoordSystem() const
134 {
135 Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) );
136 Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) );
137 return Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second );
138 }
139
getRectangle(const ShapeParentAnchor * pParentAnchor) const140 Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
141 {
142 return pParentAnchor ?
143 lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
144 getAbsRectangle();
145 }
146
getAbsRectangle() const147 Rectangle ShapeType::getAbsRectangle() const
148 {
149 const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
150 return Rectangle(
151 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true ),
152 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ),
153 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true ),
154 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true ) );
155 }
156
getRelRectangle() const157 Rectangle ShapeType::getRelRectangle() const
158 {
159 return Rectangle(
160 maTypeModel.maLeft.toInt32(),
161 maTypeModel.maTop.toInt32(),
162 maTypeModel.maWidth.toInt32(),
163 maTypeModel.maHeight.toInt32() );
164 }
165
166 // ============================================================================
167
ClientData()168 ClientData::ClientData() :
169 mnObjType( XML_TOKEN_INVALID ),
170 mnTextHAlign( XML_Left ),
171 mnTextVAlign( XML_Top ),
172 mnCol( -1 ),
173 mnRow( -1 ),
174 mnChecked( VML_CLIENTDATA_UNCHECKED ),
175 mnDropStyle( XML_Combo ),
176 mnDropLines( 1 ),
177 mnVal( 0 ),
178 mnMin( 0 ),
179 mnMax( 0 ),
180 mnInc( 0 ),
181 mnPage( 0 ),
182 mnSelType( XML_Single ),
183 mnVTEdit( VML_CLIENTDATA_TEXT ),
184 mbPrintObject( true ),
185 mbVisible( false ),
186 mbDde( false ),
187 mbNo3D( false ),
188 mbNo3D2( false ),
189 mbMultiLine( false ),
190 mbVScroll( false ),
191 mbSecretEdit( false )
192 {
193 }
194
195 // ----------------------------------------------------------------------------
196
ShapeModel()197 ShapeModel::ShapeModel()
198 {
199 }
200
~ShapeModel()201 ShapeModel::~ShapeModel()
202 {
203 }
204
createTextBox()205 TextBox& ShapeModel::createTextBox()
206 {
207 mxTextBox.reset( new TextBox );
208 return *mxTextBox;
209 }
210
createClientData()211 ClientData& ShapeModel::createClientData()
212 {
213 mxClientData.reset( new ClientData );
214 return *mxClientData;
215 }
216
217 // ----------------------------------------------------------------------------
218
ShapeBase(Drawing & rDrawing)219 ShapeBase::ShapeBase( Drawing& rDrawing ) :
220 ShapeType( rDrawing )
221 {
222 }
223
finalizeFragmentImport()224 void ShapeBase::finalizeFragmentImport()
225 {
226 // resolve shape template reference
227 if( (maShapeModel.maType.getLength() > 1) && (maShapeModel.maType[ 0 ] == '#') )
228 if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( maShapeModel.maType.copy( 1 ), true ) )
229 maTypeModel.assignUsed( pShapeType->getTypeModel() );
230 }
231
getShapeName() const232 OUString ShapeBase::getShapeName() const
233 {
234 if( maTypeModel.maShapeName.getLength() > 0 )
235 return maTypeModel.maShapeName;
236
237 OUString aBaseName = mrDrawing.getShapeBaseName( *this );
238 if( aBaseName.getLength() > 0 )
239 {
240 sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() );
241 if( nShapeIdx > 0 )
242 return OUStringBuffer( aBaseName ).append( sal_Unicode( ' ' ) ).append( nShapeIdx ).makeStringAndClear();
243 }
244
245 return OUString();
246 }
247
getChildTypeById(const OUString &) const248 const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
249 {
250 return 0;
251 }
252
getChildById(const OUString &) const253 const ShapeBase* ShapeBase::getChildById( const OUString& ) const
254 {
255 return 0;
256 }
257
convertAndInsert(const Reference<XShapes> & rxShapes,const ShapeParentAnchor * pParentAnchor) const258 Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
259 {
260 Reference< XShape > xShape;
261 if( mrDrawing.isShapeSupported( *this ) )
262 {
263 /* Calculate shape rectangle. Applications may do something special
264 according to some imported shape client data (e.g. Excel cell anchor). */
265 Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
266
267 // convert the shape, if the calculated rectangle is not empty
268 if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
269 {
270 xShape = implConvertAndInsert( rxShapes, aShapeRect );
271 if( xShape.is() )
272 {
273 // set imported or generated shape name (not supported by form controls)
274 PropertySet aShapeProp( xShape );
275 if( aShapeProp.hasProperty( PROP_Name ) )
276 aShapeProp.setProperty( PROP_Name, getShapeName() );
277
278 /* Notify the drawing that a new shape has been inserted. For
279 convenience, pass the rectangle that contains position and
280 size of the shape. */
281 bool bGroupChild = pParentAnchor != 0;
282 mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild );
283 }
284 }
285 }
286 return xShape;
287 }
288
convertFormatting(const Reference<XShape> & rxShape,const ShapeParentAnchor * pParentAnchor) const289 void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const
290 {
291 if( rxShape.is() )
292 {
293 /* Calculate shape rectangle. Applications may do something special
294 according to some imported shape client data (e.g. Excel cell anchor). */
295 Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
296
297 // convert the shape, if the calculated rectangle is not empty
298 if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
299 {
300 rxShape->setPosition( Point( aShapeRect.X, aShapeRect.Y ) );
301 rxShape->setSize( Size( aShapeRect.Width, aShapeRect.Height ) );
302 convertShapeProperties( rxShape );
303 }
304 }
305 }
306
307 // protected ------------------------------------------------------------------
308
calcShapeRectangle(const ShapeParentAnchor * pParentAnchor) const309 Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
310 {
311 /* Calculate shape rectangle. Applications may do something special
312 according to some imported shape client data (e.g. Excel cell anchor). */
313 Rectangle aShapeRect;
314 const ClientData* pClientData = getClientData();
315 if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) )
316 aShapeRect = getRectangle( pParentAnchor );
317 return aShapeRect;
318 }
319
convertShapeProperties(const Reference<XShape> & rxShape) const320 void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
321 {
322 ::oox::drawingml::ShapePropertyMap aPropMap( mrDrawing.getFilter().getModelObjectHelper() );
323 const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
324 maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper );
325 maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper );
326 PropertySet( rxShape ).setProperties( aPropMap );
327 }
328
329 // ============================================================================
330
SimpleShape(Drawing & rDrawing,const OUString & rService)331 SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :
332 ShapeBase( rDrawing ),
333 maService( rService )
334 {
335 }
336
implConvertAndInsert(const Reference<XShapes> & rxShapes,const Rectangle & rShapeRect) const337 Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
338 {
339 Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, rShapeRect );
340 convertShapeProperties( xShape );
341 return xShape;
342 }
343
344 // ============================================================================
345
RectangleShape(Drawing & rDrawing)346 RectangleShape::RectangleShape( Drawing& rDrawing ) :
347 SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ) )
348 {
349 }
350
351 // ============================================================================
352
EllipseShape(Drawing & rDrawing)353 EllipseShape::EllipseShape( Drawing& rDrawing ) :
354 SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ) )
355 {
356 }
357
358 // ============================================================================
359
PolyLineShape(Drawing & rDrawing)360 PolyLineShape::PolyLineShape( Drawing& rDrawing ) :
361 SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ) )
362 {
363 }
364
implConvertAndInsert(const Reference<XShapes> & rxShapes,const Rectangle & rShapeRect) const365 Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
366 {
367 Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
368 // polygon path
369 Rectangle aCoordSys = getCoordSystem();
370 if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
371 {
372 ::std::vector< Point > aAbsPoints;
373 for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
374 aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
375 PointSequenceSequence aPointSeq( 1 );
376 aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
377 PropertySet aPropSet( xShape );
378 aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
379 }
380 return xShape;
381 }
382
383 // ============================================================================
384
CustomShape(Drawing & rDrawing)385 CustomShape::CustomShape( Drawing& rDrawing ) :
386 SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.CustomShape" ) )
387 {
388 }
389
implConvertAndInsert(const Reference<XShapes> & rxShapes,const Rectangle & rShapeRect) const390 Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
391 {
392 // try to create a custom shape
393 Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
394 if( xShape.is() ) try
395 {
396 // create the custom shape geometry
397 Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
398 xDefaulter->createCustomShapeDefaults( OUString::valueOf( getShapeType() ) );
399 // convert common properties
400 convertShapeProperties( xShape );
401 }
402 catch( Exception& )
403 {
404 }
405 return xShape;
406 }
407
408 // ============================================================================
409
ComplexShape(Drawing & rDrawing)410 ComplexShape::ComplexShape( Drawing& rDrawing ) :
411 CustomShape( rDrawing )
412 {
413 }
414
implConvertAndInsert(const Reference<XShapes> & rxShapes,const Rectangle & rShapeRect) const415 Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
416 {
417 XmlFilterBase& rFilter = mrDrawing.getFilter();
418 sal_Int32 nShapeType = getShapeType();
419 OUString aGraphicPath = getGraphicPath();
420
421 // try to find registered OLE object info
422 if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
423 {
424 OSL_ENSURE( nShapeType == VML_SHAPETYPE_PICTUREFRAME, "ComplexShape::implConvertAndInsert - unexpected shape type" );
425
426 // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
427 if( pOleObjectInfo->mbDmlShape )
428 return Reference< XShape >();
429
430 PropertyMap aOleProps;
431 Size aOleSize( rShapeRect.Width, rShapeRect.Height );
432 if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
433 {
434 Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rxShapes, rShapeRect );
435 if( xShape.is() )
436 {
437 // set the replacement graphic
438 if( aGraphicPath.getLength() > 0 )
439 {
440 Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
441 if( xGraphic.is() )
442 aOleProps[ PROP_Graphic ] <<= xGraphic;
443 }
444
445 PropertySet aPropSet( xShape );
446 aPropSet.setProperties( aOleProps );
447
448 return xShape;
449 }
450 }
451 }
452
453 // try to find registered form control info
454 const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
455 if( pControlInfo && (pControlInfo->maFragmentPath.getLength() > 0) )
456 {
457 OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
458 OUString aShapeName = getShapeName();
459 if( aShapeName.getLength() > 0 )
460 {
461 OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
462 // load the control properties from fragment
463 ::oox::ole::EmbeddedControl aControl( aShapeName );
464 if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
465 {
466 // create and return the control shape (including control model)
467 sal_Int32 nCtrlIndex = -1;
468 Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
469 // on error, proceed and try to create picture from replacement image
470 if( xShape.is() )
471 return xShape;
472 }
473 }
474 }
475
476 // host application wants to create the shape (do not try failed OLE controls again)
477 if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo )
478 {
479 OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" );
480 Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect );
481 if( xShape.is() )
482 return xShape;
483 }
484
485 // try to create a picture object
486 if( aGraphicPath.getLength() > 0 )
487 {
488 Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rxShapes, rShapeRect );
489 if( xShape.is() )
490 {
491 OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( aGraphicPath );
492 if( aGraphicUrl.getLength() > 0 )
493 {
494 PropertySet aPropSet( xShape );
495 aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
496 }
497 }
498 return xShape;
499 }
500
501 // default: try to create a custom shape
502 return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
503 }
504
505 // ============================================================================
506
GroupShape(Drawing & rDrawing)507 GroupShape::GroupShape( Drawing& rDrawing ) :
508 ShapeBase( rDrawing ),
509 mxChildren( new ShapeContainer( rDrawing ) )
510 {
511 }
512
~GroupShape()513 GroupShape::~GroupShape()
514 {
515 }
516
finalizeFragmentImport()517 void GroupShape::finalizeFragmentImport()
518 {
519 // basic shape processing
520 ShapeBase::finalizeFragmentImport();
521 // finalize all child shapes
522 mxChildren->finalizeFragmentImport();
523 }
524
getChildTypeById(const OUString & rShapeId) const525 const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
526 {
527 return mxChildren->getShapeTypeById( rShapeId, true );
528 }
529
getChildById(const OUString & rShapeId) const530 const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
531 {
532 return mxChildren->getShapeById( rShapeId, true );
533 }
534
implConvertAndInsert(const Reference<XShapes> & rxShapes,const Rectangle & rShapeRect) const535 Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
536 {
537 Reference< XShape > xGroupShape;
538 // check that this shape contains children and a valid coordinate system
539 ShapeParentAnchor aParentAnchor;
540 aParentAnchor.maShapeRect = rShapeRect;
541 aParentAnchor.maCoordSys = getCoordSystem();
542 if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
543 {
544 xGroupShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rxShapes, rShapeRect );
545 Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
546 mxChildren->convertAndInsert( xChildShapes, &aParentAnchor );
547 // no child shape has been created - delete the group shape
548 if( !xChildShapes->hasElements() )
549 {
550 rxShapes->remove( xGroupShape );
551 xGroupShape.clear();
552 }
553 }
554 catch( Exception& )
555 {
556 }
557 return xGroupShape;
558 }
559
560 // ============================================================================
561
562 } // namespace vml
563 } // namespace oox
564