bump product version to 4.2.0.1
[LibreOffice.git] / oox / source / vml / vmlshape.cxx
blob7b8c9eb661959cbc170fce8bf3df55017493a8ff
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <algorithm>
21 #include <boost/optional.hpp>
23 #include "oox/vml/vmlshape.hxx"
25 #include <com/sun/star/beans/PropertyValues.hpp>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <com/sun/star/awt/XControlModel.hpp>
28 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
29 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
30 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
31 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
32 #include <com/sun/star/drawing/XShapes.hpp>
33 #include <com/sun/star/drawing/XControlShape.hpp>
34 #include <com/sun/star/graphic/XGraphic.hpp>
35 #include <com/sun/star/table/BorderLine2.hpp>
36 #include <com/sun/star/text/HoriOrientation.hpp>
37 #include <com/sun/star/text/RelOrientation.hpp>
38 #include <com/sun/star/text/SizeType.hpp>
39 #include <com/sun/star/text/VertOrientation.hpp>
40 #include <com/sun/star/text/WrapTextMode.hpp>
41 #include <com/sun/star/text/XTextContent.hpp>
42 #include <com/sun/star/text/XTextDocument.hpp>
43 #include <com/sun/star/text/XTextFrame.hpp>
44 #include <com/sun/star/text/TextContentAnchorType.hpp>
45 #include <rtl/math.hxx>
46 #include <rtl/ustrbuf.hxx>
47 #include <svx/svdtrans.hxx>
48 #include "oox/drawingml/shapepropertymap.hxx"
49 #include "oox/helper/graphichelper.hxx"
50 #include "oox/helper/propertyset.hxx"
51 #include "oox/ole/axcontrol.hxx"
52 #include "oox/ole/axcontrolfragment.hxx"
53 #include "oox/ole/oleobjecthelper.hxx"
54 #include "oox/vml/vmldrawing.hxx"
55 #include "oox/vml/vmlshapecontainer.hxx"
56 #include "oox/vml/vmltextbox.hxx"
57 #include "oox/core/xmlfilterbase.hxx"
58 #include "oox/helper/containerhelper.hxx"
60 using ::com::sun::star::beans::XPropertySet;
61 using ::com::sun::star::uno::Any;
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::text;
66 namespace oox {
67 namespace vml {
69 // ============================================================================
71 using namespace ::com::sun::star;
72 using namespace ::com::sun::star::drawing;
73 using namespace ::com::sun::star::graphic;
74 using namespace ::com::sun::star::uno;
75 using namespace ::com::sun::star::io;
77 using ::oox::core::XmlFilterBase;
79 // ============================================================================
81 namespace {
83 const sal_Int32 VML_SHAPETYPE_PICTUREFRAME = 75;
84 const sal_Int32 VML_SHAPETYPE_HOSTCONTROL = 201;
86 // ----------------------------------------------------------------------------
88 awt::Point lclGetAbsPoint( const awt::Point& rRelPoint, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
90 double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
91 double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
92 awt::Point aAbsPoint;
93 aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
94 aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
95 return aAbsPoint;
98 awt::Rectangle lclGetAbsRect( const awt::Rectangle& rRelRect, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
100 double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
101 double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
102 awt::Rectangle aAbsRect;
103 aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
104 aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
105 aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
106 aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
107 return aAbsRect;
110 } // namespace
112 // ============================================================================
114 ShapeTypeModel::ShapeTypeModel():
115 mbAutoHeight( sal_False ),
116 mbVisible( sal_True )
120 void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
122 moShapeType.assignIfUsed( rSource.moShapeType );
123 moCoordPos.assignIfUsed( rSource.moCoordPos );
124 moCoordSize.assignIfUsed( rSource.moCoordSize );
125 /* The style properties position, left, top, width, height, margin-left,
126 margin-top are not derived from shape template to shape. */
127 maStrokeModel.assignUsed( rSource.maStrokeModel );
128 maFillModel.assignUsed( rSource.maFillModel );
129 moGraphicPath.assignIfUsed( rSource.moGraphicPath );
130 moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
133 // ----------------------------------------------------------------------------
135 ShapeType::ShapeType( Drawing& rDrawing ) :
136 mrDrawing( rDrawing )
140 ShapeType::~ShapeType()
144 sal_Int32 ShapeType::getShapeType() const
146 return maTypeModel.moShapeType.get( 0 );
149 OUString ShapeType::getGraphicPath() const
151 return maTypeModel.moGraphicPath.get( OUString() );
154 awt::Rectangle ShapeType::getCoordSystem() const
156 Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) );
157 Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) );
158 if( aCoordSize.first == 0 )
159 aCoordSize.first = 1;
160 if( aCoordSize.second == 0 )
161 aCoordSize.second = 1;
162 return awt::Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second );
165 awt::Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
167 return pParentAnchor ?
168 lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
169 getAbsRectangle();
172 awt::Rectangle ShapeType::getAbsRectangle() const
174 const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
176 sal_Int32 nWidth = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true );
177 if ( nWidth == 0 )
178 nWidth = 1;
180 sal_Int32 nHeight = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true );
181 if ( nHeight == 0 )
182 nHeight = 1;
184 sal_Int32 nLeft = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true )
185 + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true );
186 if (nLeft == 0 && maTypeModel.maPosition == "absolute")
187 nLeft = 1;
189 return awt::Rectangle(
190 nLeft,
191 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ),
192 nWidth, nHeight );
195 awt::Rectangle ShapeType::getRelRectangle() const
197 sal_Int32 nWidth = maTypeModel.maWidth.toInt32();
198 if ( nWidth == 0 )
199 nWidth = 1;
201 sal_Int32 nHeight = maTypeModel.maHeight.toInt32();
202 if ( nHeight == 0 )
203 nHeight = 1;
205 return awt::Rectangle(
206 maTypeModel.maLeft.toInt32(),
207 maTypeModel.maTop.toInt32(),
208 nWidth, nHeight );
211 // ============================================================================
213 ClientData::ClientData() :
214 mnObjType( XML_TOKEN_INVALID ),
215 mnTextHAlign( XML_Left ),
216 mnTextVAlign( XML_Top ),
217 mnCol( -1 ),
218 mnRow( -1 ),
219 mnChecked( VML_CLIENTDATA_UNCHECKED ),
220 mnDropStyle( XML_Combo ),
221 mnDropLines( 1 ),
222 mnVal( 0 ),
223 mnMin( 0 ),
224 mnMax( 0 ),
225 mnInc( 0 ),
226 mnPage( 0 ),
227 mnSelType( XML_Single ),
228 mnVTEdit( VML_CLIENTDATA_TEXT ),
229 mbPrintObject( true ),
230 mbVisible( false ),
231 mbDde( false ),
232 mbNo3D( false ),
233 mbNo3D2( false ),
234 mbMultiLine( false ),
235 mbVScroll( false ),
236 mbSecretEdit( false )
240 // ----------------------------------------------------------------------------
242 ShapeModel::ShapeModel()
246 ShapeModel::~ShapeModel()
250 TextBox& ShapeModel::createTextBox(ShapeTypeModel& rModel)
252 mxTextBox.reset( new TextBox(rModel) );
253 return *mxTextBox;
256 ClientData& ShapeModel::createClientData()
258 mxClientData.reset( new ClientData );
259 return *mxClientData;
262 // ----------------------------------------------------------------------------
264 ShapeBase::ShapeBase( Drawing& rDrawing ) :
265 ShapeType( rDrawing )
269 void ShapeBase::finalizeFragmentImport()
271 if( maShapeModel.maType.getLength() > 1 )
273 OUString aType = maShapeModel.maType;
274 if (aType[ 0 ] == '#')
275 aType = aType.copy(1);
276 if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( aType, true ) )
277 maTypeModel.assignUsed( pShapeType->getTypeModel() );
281 OUString ShapeBase::getShapeName() const
283 if( !maTypeModel.maShapeName.isEmpty() )
284 return maTypeModel.maShapeName;
286 OUString aBaseName = mrDrawing.getShapeBaseName( *this );
287 if( !aBaseName.isEmpty() )
289 sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() );
290 if( nShapeIdx > 0 )
291 return OUStringBuffer( aBaseName ).append( ' ' ).append( nShapeIdx ).makeStringAndClear();
294 return OUString();
297 const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
299 return 0;
302 const ShapeBase* ShapeBase::getChildById( const OUString& ) const
304 return 0;
307 Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
309 Reference< XShape > xShape;
310 if( mrDrawing.isShapeSupported( *this ) )
312 /* Calculate shape rectangle. Applications may do something special
313 according to some imported shape client data (e.g. Excel cell anchor). */
314 awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
316 if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
318 xShape = implConvertAndInsert( rxShapes, aShapeRect );
319 if( xShape.is() )
321 // set imported or generated shape name (not supported by form controls)
322 PropertySet aShapeProp( xShape );
323 if( aShapeProp.hasProperty( PROP_Name ) )
324 aShapeProp.setProperty( PROP_Name, getShapeName() );
325 Reference< XControlShape > xControlShape( xShape, uno::UNO_QUERY );
326 if ( xControlShape.is() && !getTypeModel().mbVisible )
328 PropertySet aControlShapeProp( xControlShape->getControl() );
329 aControlShapeProp.setProperty( PROP_EnableVisible, uno::makeAny( sal_False ) );
331 /* Notify the drawing that a new shape has been inserted. For
332 convenience, pass the rectangle that contains position and
333 size of the shape. */
334 bool bGroupChild = pParentAnchor != 0;
335 mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild );
338 else
339 SAL_WARN("oox", "not converting shape, as calculated rectangle is empty");
341 return xShape;
344 void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const
346 if( rxShape.is() )
348 /* Calculate shape rectangle. Applications may do something special
349 according to some imported shape client data (e.g. Excel cell anchor). */
350 awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
352 // convert the shape, if the calculated rectangle is not empty
353 if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
355 rxShape->setPosition( awt::Point( aShapeRect.X, aShapeRect.Y ) );
356 rxShape->setSize( awt::Size( aShapeRect.Width, aShapeRect.Height ) );
357 convertShapeProperties( rxShape );
362 // protected ------------------------------------------------------------------
364 awt::Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
366 /* Calculate shape rectangle. Applications may do something special
367 according to some imported shape client data (e.g. Excel cell anchor). */
368 awt::Rectangle aShapeRect;
369 const ClientData* pClientData = getClientData();
370 if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) )
371 aShapeRect = getRectangle( pParentAnchor );
372 return aShapeRect;
375 void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
377 ::oox::drawingml::ShapePropertyMap aPropMap( mrDrawing.getFilter().getModelObjectHelper() );
378 const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
379 maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper );
380 maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper );
382 uno::Reference<lang::XServiceInfo> xSInfo(rxShape, uno::UNO_QUERY_THROW);
383 if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
385 // Any other service supporting the ShadowFormat property?
386 maTypeModel.maShadowModel.pushToPropMap(aPropMap, rGraphicHelper);
387 // TextFrames have BackColor, not FillColor
388 if (aPropMap.hasProperty(PROP_FillColor))
390 aPropMap.setProperty(PROP_BackColor, aPropMap[PROP_FillColor]);
391 aPropMap.erase(PROP_FillColor);
393 // TextFrames have BackColorTransparency, not FillTransparence
394 if (aPropMap.hasProperty(PROP_FillTransparence))
396 aPropMap.setProperty(PROP_BackColorTransparency, aPropMap[PROP_FillTransparence]);
397 aPropMap.erase(PROP_FillTransparence);
399 // And no LineColor property; individual borders can have colors and widths
400 boost::optional<sal_Int32> oLineWidth;
401 if (maTypeModel.maStrokeModel.moWeight.has())
402 oLineWidth.reset(ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maTypeModel.maStrokeModel.moWeight.get(), 0, false, false));
403 if (aPropMap.hasProperty(PROP_LineColor))
405 uno::Reference<beans::XPropertySet> xPropertySet(rxShape, uno::UNO_QUERY);
406 static const sal_Int32 aBorders[] = {
407 PROP_TopBorder, PROP_LeftBorder, PROP_BottomBorder, PROP_RightBorder
409 for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
411 table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(PropertyMap::getPropertyName(aBorders[i])).get<table::BorderLine2>();
412 aBorderLine.Color = aPropMap[PROP_LineColor].get<sal_Int32>();
413 if (oLineWidth)
414 aBorderLine.LineWidth = *oLineWidth;
415 aPropMap.setProperty(aBorders[i], uno::makeAny(aBorderLine));
417 aPropMap.erase(PROP_LineColor);
420 else if (xSInfo->supportsService("com.sun.star.drawing.CustomShape"))
421 maTypeModel.maTextpathModel.pushToPropMap(aPropMap, rxShape);
423 PropertySet( rxShape ).setProperties( aPropMap );
426 // ============================================================================
428 SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :
429 ShapeBase( rDrawing ),
430 maService( rService )
434 void lcl_setSurround(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
436 sal_Int32 nSurround = com::sun::star::text::WrapTextMode_THROUGHT;
437 if ( rTypeModel.moWrapType.get() == "square" || rTypeModel.moWrapType .get()== "tight" ||
438 rTypeModel.moWrapType.get() == "through" )
440 nSurround = com::sun::star::text::WrapTextMode_PARALLEL;
441 if ( rTypeModel.moWrapSide.get() == "left" )
442 nSurround = com::sun::star::text::WrapTextMode_LEFT;
443 else if ( rTypeModel.moWrapSide.get() == "right" )
444 nSurround = com::sun::star::text::WrapTextMode_RIGHT;
446 else if ( rTypeModel.moWrapType.get() == "topAndBottom" )
447 nSurround = com::sun::star::text::WrapTextMode_NONE;
449 rPropSet.setProperty(PROP_Surround, nSurround);
452 void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
454 if ( rTypeModel.maPositionHorizontal == "center" )
455 rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));
457 if ( rTypeModel.maPositionHorizontalRelative == "page" )
458 rPropSet.setAnyProperty(PROP_HoriOrientRelation, makeAny(text::RelOrientation::PAGE_FRAME));
460 if ( rTypeModel.maPositionVertical == "center" )
461 rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::CENTER));
463 if ( rTypeModel.maPosition == "absolute" )
465 // Word supports as-character (inline) and at-character only, absolute can't be inline.
466 rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
468 if ( rTypeModel.maPositionVerticalRelative == "page" )
470 rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
472 else if ( rTypeModel.maPositionVerticalRelative == "margin" )
474 rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_PRINT_AREA);
476 else
478 // Vertical placement relative to margin, because parent style must not modify vertical position
479 rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
482 else if( rTypeModel.maPosition == "relative" )
483 { // I'm not very sure this is correct either.
484 rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PARAGRAPH);
486 else // static (is the default) means anchored inline
488 rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AS_CHARACTER);
490 lcl_setSurround( rPropSet, rTypeModel );
493 void lcl_SetRotation(PropertySet& rPropSet, const sal_Int32 nRotation)
495 // See DffPropertyReader::Fix16ToAngle(): in VML, positive rotation angles are clockwise, we have them as counter-clockwise.
496 // Additionally, VML type is 0..360, our is 0..36000.
497 rPropSet.setAnyProperty(PROP_RotateAngle, makeAny(sal_Int32(NormAngle360(nRotation * -100))));
500 Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
502 awt::Rectangle aShapeRect(rShapeRect);
503 boost::optional<sal_Int32> oRotation;
504 bool bFlipX = false, bFlipY = false;
505 if (!maTypeModel.maRotation.isEmpty())
506 oRotation.reset(maTypeModel.maRotation.toInt32());
507 if (!maTypeModel.maFlip.isEmpty())
509 if (maTypeModel.maFlip.equalsAscii("x"))
511 bFlipX = true;
513 else if (maTypeModel.maFlip.equalsAscii("y"))
515 bFlipY = true;
519 Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, aShapeRect );
520 convertShapeProperties( xShape );
522 // Handle left/right/top/bottom wrap distance.
523 // Default value of mso-wrap-distance-left/right is supposed to be 0 (see
524 // 19.1.2.19 of the VML spec), but Word implements a non-zero value.
525 // [MS-ODRAW] says the below default value in 2.3.4.9.
526 const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
527 OUString aWrapDistanceLeft = OUString::number(0x0001BE7C);
528 if (!maTypeModel.maWrapDistanceLeft.isEmpty())
529 aWrapDistanceLeft = maTypeModel.maWrapDistanceLeft;
530 sal_Int32 nWrapDistanceLeft = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, aWrapDistanceLeft, 0, true, false);
531 PropertySet(xShape).setAnyProperty(PROP_LeftMargin, uno::makeAny(nWrapDistanceLeft));
532 OUString aWrapDistanceRight = OUString::number(0x0001BE7C);
533 if (!maTypeModel.maWrapDistanceRight.isEmpty())
534 aWrapDistanceRight = maTypeModel.maWrapDistanceRight;
535 sal_Int32 nWrapDistanceRight = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, aWrapDistanceRight, 0, true, false);
536 PropertySet(xShape).setAnyProperty(PROP_RightMargin, uno::makeAny(nWrapDistanceRight));
537 sal_Int32 nWrapDistanceTop = 0;
538 if (!maTypeModel.maWrapDistanceTop.isEmpty())
539 nWrapDistanceTop = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maTypeModel.maWrapDistanceTop, 0, false, true);
540 PropertySet(xShape).setAnyProperty(PROP_TopMargin, uno::makeAny(nWrapDistanceTop));
541 sal_Int32 nWrapDistanceBottom = 0;
542 if (!maTypeModel.maWrapDistanceBottom.isEmpty())
543 nWrapDistanceBottom = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maTypeModel.maWrapDistanceBottom, 0, false, true);
544 PropertySet(xShape).setAnyProperty(PROP_BottomMargin, uno::makeAny(nWrapDistanceBottom));
546 if ( maService.equalsAscii( "com.sun.star.text.TextFrame" ) )
548 PropertySet( xShape ).setAnyProperty( PROP_FrameIsAutomaticHeight, makeAny( maTypeModel.mbAutoHeight ) );
549 PropertySet( xShape ).setAnyProperty( PROP_SizeType, makeAny( maTypeModel.mbAutoHeight ? SizeType::MIN : SizeType::FIX ) );
550 if( getTextBox()->borderDistanceSet )
552 PropertySet( xShape ).setAnyProperty( PROP_LeftBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceLeft )));
553 PropertySet( xShape ).setAnyProperty( PROP_TopBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceTop )));
554 PropertySet( xShape ).setAnyProperty( PROP_RightBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceRight )));
555 PropertySet( xShape ).setAnyProperty( PROP_BottomBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceBottom )));
557 if (!maTypeModel.maLayoutFlowAlt.isEmpty())
559 // Can't handle this property here, as the frame is not attached yet: pass it to writerfilter.
560 uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
561 uno::Sequence<beans::PropertyValue> aGrabBag;
562 xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
563 beans::PropertyValue aPair;
564 aPair.Name = "mso-layout-flow-alt";
565 aPair.Value = uno::makeAny(maTypeModel.maLayoutFlowAlt);
566 if (aGrabBag.hasElements())
568 sal_Int32 nLength = aGrabBag.getLength();
569 aGrabBag.realloc(nLength + 1);
570 aGrabBag[nLength] = aPair;
572 else
574 aGrabBag.realloc(1);
575 aGrabBag[0] = aPair;
577 xPropertySet->setPropertyValue("FrameInteropGrabBag", uno::makeAny(aGrabBag));
580 else
582 // FIXME Setting the relative width/heigh only for everything but text frames as
583 // TextFrames already have relative widht/heigh feature... but currently not working
584 // in the way we need.
586 // Set the relative width / height if any
587 if ( !maTypeModel.maWidthPercent.isEmpty( ) )
589 // Only page-relative width is supported ATM
590 if ( maTypeModel.maWidthRelative.isEmpty() || maTypeModel.maWidthRelative == "page" )
592 sal_Int16 nWidth = maTypeModel.maWidthPercent.toInt32() / 10;
593 // Only apply if nWidth != 0
594 if ( nWidth )
595 PropertySet( xShape ).setAnyProperty(PROP_RelativeWidth, makeAny( nWidth ) );
598 if ( !maTypeModel.maHeightPercent.isEmpty( ) )
600 // Only page-relative height is supported ATM
601 if ( maTypeModel.maHeightRelative.isEmpty() || maTypeModel.maHeightRelative == "page" )
603 sal_Int16 nHeight = maTypeModel.maHeightPercent.toInt32() / 10;
604 // Only apply if nHeight != 0
605 if ( nHeight )
606 PropertySet( xShape ).setAnyProperty(PROP_RelativeHeight, makeAny( nHeight ) );
610 // drawinglayer default is center, MSO default is top.
611 drawing::TextVerticalAdjust eTextVerticalAdjust = drawing::TextVerticalAdjust_TOP;
612 if (maTypeModel.maVTextAnchor == "middle")
613 eTextVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
614 else if (maTypeModel.maVTextAnchor == "bottom")
615 eTextVerticalAdjust = drawing::TextVerticalAdjust_BOTTOM;
616 PropertySet(xShape).setAnyProperty(PROP_TextVerticalAdjust, makeAny(eTextVerticalAdjust));
618 if (getTextBox())
620 getTextBox()->convert(xShape);
621 if (getTextBox()->borderDistanceSet)
623 PropertySet(xShape).setAnyProperty(PROP_TextLeftDistance, makeAny(sal_Int32(getTextBox()->borderDistanceLeft)));
624 PropertySet(xShape).setAnyProperty(PROP_TextUpperDistance, makeAny(sal_Int32(getTextBox()->borderDistanceTop)));
625 PropertySet(xShape).setAnyProperty(PROP_TextRightDistance, makeAny(sal_Int32(getTextBox()->borderDistanceRight)));
626 PropertySet(xShape).setAnyProperty(PROP_TextLowerDistance, makeAny(sal_Int32(getTextBox()->borderDistanceBottom)));
631 // Import Legacy Fragments (if any)
632 if( xShape.is() && !maShapeModel.maLegacyDiagramPath.isEmpty() )
634 Reference< XInputStream > xInStrm( mrDrawing.getFilter().openInputStream( maShapeModel.maLegacyDiagramPath ), UNO_SET_THROW );
635 if( xInStrm.is() )
636 PropertySet( xShape ).setProperty( PROP_LegacyFragment, xInStrm );
639 PropertySet aPropertySet(xShape);
640 if (xShape.is())
642 if (oRotation)
644 lcl_SetRotation(aPropertySet, *oRotation);
645 // If rotation is used, simple setPosition() is not enough.
646 aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) );
647 aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) );
650 // When flip has 'x' or 'y', the associated ShapeRect will be changed but direction change doesn't occur.
651 // It might occur internally in SdrObject of "sw" module, not here.
652 // The associated properties "PROP_MirroredX" and "PROP_MirroredY" have to be set here so that direction change will occur internally.
653 if (bFlipX || bFlipY)
655 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aPropSequence (2);
656 int nPropertyIndex = 0;
657 if (bFlipX)
659 aPropSequence [nPropertyIndex].Name = "MirroredX";
660 aPropSequence [nPropertyIndex].Value = makeAny (bFlipX);
661 nPropertyIndex++;
663 if (bFlipY)
665 aPropSequence [nPropertyIndex].Name = "MirroredY";
666 aPropSequence [nPropertyIndex].Value = makeAny (bFlipY);
667 nPropertyIndex++;
669 aPropertySet.setAnyProperty(PROP_CustomShapeGeometry, makeAny( aPropSequence ) );
673 lcl_SetAnchorType(aPropertySet, maTypeModel);
675 return xShape;
678 Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString& rGraphicPath ) const
680 Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GraphicObjectShape", rxShapes, rShapeRect );
681 if( xShape.is() )
683 XmlFilterBase& rFilter = mrDrawing.getFilter();
684 OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( rGraphicPath );
685 PropertySet aPropSet( xShape );
686 if( !aGraphicUrl.isEmpty() )
688 aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
690 uno::Reference< lang::XServiceInfo > xServiceInfo(rxShapes, uno::UNO_QUERY);
691 // If the shape has an absolute position, set the properties accordingly, unless we're inside a group shape.
692 if ( maTypeModel.maPosition == "absolute" && !xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
694 aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
695 aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
696 aPropSet.setProperty(PROP_Opaque, sal_False);
698 // fdo#70457: preserve rotation information
699 if ( !maTypeModel.maRotation.isEmpty() )
700 lcl_SetRotation( aPropSet, maTypeModel.maRotation.toInt32() );
702 lcl_SetAnchorType(aPropSet, maTypeModel);
704 return xShape;
707 // ============================================================================
709 RectangleShape::RectangleShape( Drawing& rDrawing ) :
710 SimpleShape( rDrawing, "com.sun.star.drawing.RectangleShape" )
714 Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const awt::Rectangle& rShapeRect) const
716 OUString aGraphicPath = getGraphicPath();
718 // try to create a picture object
719 if(!aGraphicPath.isEmpty())
720 return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
722 // default: try to create a rectangle shape
723 Reference<XShape> xShape = SimpleShape::implConvertAndInsert(rxShapes, rShapeRect);
724 OUString sArcsize = maTypeModel.maArcsize;
725 if ( !sArcsize.isEmpty( ) )
727 sal_Unicode cLastChar = sArcsize[sArcsize.getLength() - 1];
728 sal_Int32 nValue = sArcsize.copy( 0, sArcsize.getLength() - 1 ).toInt32( );
729 // Get the smallest half-side
730 double size = std::min( rShapeRect.Height, rShapeRect.Width ) / 2.0;
731 sal_Int32 nRadius = 0;
732 if ( cLastChar == 'f' )
733 nRadius = size * nValue / 65536;
734 else if ( cLastChar == '%' )
735 nRadius = size * nValue / 100;
736 PropertySet( xShape ).setAnyProperty( PROP_CornerRadius, makeAny( nRadius ) );
738 return xShape;
741 // ============================================================================
743 EllipseShape::EllipseShape( Drawing& rDrawing ) :
744 SimpleShape( rDrawing, "com.sun.star.drawing.EllipseShape" )
748 // ============================================================================
750 PolyLineShape::PolyLineShape( Drawing& rDrawing ) :
751 SimpleShape( rDrawing, "com.sun.star.drawing.PolyLineShape" )
755 Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
757 Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
758 // polygon path
759 awt::Rectangle aCoordSys = getCoordSystem();
760 if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
762 ::std::vector< awt::Point > aAbsPoints;
763 for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
764 aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
765 PointSequenceSequence aPointSeq( 1 );
766 aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
767 PropertySet aPropSet( xShape );
768 aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
770 return xShape;
773 LineShape::LineShape(Drawing& rDrawing)
774 : SimpleShape(rDrawing, "com.sun.star.drawing.LineShape")
778 awt::Rectangle LineShape::getAbsRectangle() const
780 const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
781 awt::Rectangle aShapeRect;
782 sal_Int32 nIndex = 0;
784 aShapeRect.X = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, true, true);
785 aShapeRect.Y = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, false, true);
786 nIndex = 0;
787 aShapeRect.Width = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, true, true) - aShapeRect.X;
788 aShapeRect.Height = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, false, true) - aShapeRect.Y;
789 return aShapeRect;
792 awt::Rectangle LineShape::getRelRectangle() const
794 awt::Rectangle aShapeRect;
795 sal_Int32 nIndex = 0;
797 aShapeRect.X = maShapeModel.maFrom.getToken(0, ',', nIndex).toInt32();
798 aShapeRect.Y = maShapeModel.maFrom.getToken(0, ',', nIndex).toInt32();
799 nIndex = 0;
800 aShapeRect.Width = maShapeModel.maTo.getToken(0, ',', nIndex).toInt32() - aShapeRect.X;
801 aShapeRect.Height = maShapeModel.maTo.getToken(0, ',', nIndex).toInt32() - aShapeRect.Y;
802 return aShapeRect;
805 // ============================================================================
807 BezierShape::BezierShape(Drawing& rDrawing)
808 : SimpleShape(rDrawing, "com.sun.star.drawing.OpenBezierShape")
812 Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
814 // If we have an 'x' in the last part of the path it means it is closed...
815 sal_Int32 nPos = maShapeModel.maVmlPath.lastIndexOf(',');
816 if ( nPos != -1 && maShapeModel.maVmlPath.copy(nPos).indexOf('x') != -1 )
818 const_cast<BezierShape*>( this )->setService( "com.sun.star.drawing.ClosedBezierShape" );
821 awt::Rectangle aCoordSys = getCoordSystem();
822 PolyPolygonBezierCoords aBezierCoords;
824 if( (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
826 const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
828 // Bezier paths may consist of one or more sub-paths
829 typedef ::std::vector< ::std::vector< awt::Point > > SubPathList;
830 typedef ::std::vector< ::std::vector< PolygonFlags > > FlagsList;
831 SubPathList aCoordLists;
832 FlagsList aFlagLists;
833 sal_Int32 nIndex = 0;
835 // Curve defined by to, from, control1 and control2 attributes
836 if ( maShapeModel.maVmlPath.isEmpty() )
838 aCoordLists.push_back( ::std::vector< awt::Point >() );
839 aFlagLists.push_back( ::std::vector< PolygonFlags >() );
841 // Start point
842 aCoordLists[ 0 ].push_back(
843 awt::Point(ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, true, true ),
844 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, false, true ) ) );
845 // Control point 1
846 aCoordLists[ 0 ].push_back(
847 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, true, true ),
848 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, false, true ) ) );
849 // Control point 2
850 aCoordLists[ 0 ].push_back(
851 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, true, true ),
852 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, false, true ) ) );
853 // End point
854 aCoordLists[ 0 ].push_back(
855 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, true, true ),
856 ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, false, true ) ) );
858 // First and last points are normals, points 2 and 4 are controls
859 aFlagLists[ 0 ].resize( aCoordLists[ 0 ].size(), PolygonFlags_CONTROL );
860 aFlagLists[ 0 ][ 0 ] = PolygonFlags_NORMAL;
861 aFlagLists[ 0 ].back() = PolygonFlags_NORMAL;
863 // Curve defined by path attribute
864 else
866 // Parse VML path string and convert to absolute coordinates
867 ConversionHelper::decodeVmlPath( aCoordLists, aFlagLists, maShapeModel.maVmlPath );
869 for ( SubPathList::iterator aListIt = aCoordLists.begin(); aListIt != aCoordLists.end(); ++aListIt )
870 for ( ::std::vector< awt::Point >::iterator aPointIt = (*aListIt).begin(); aPointIt != (*aListIt).end(); ++aPointIt)
872 (*aPointIt) = lclGetAbsPoint( (*aPointIt), rShapeRect, aCoordSys );
876 aBezierCoords.Coordinates.realloc( aCoordLists.size() );
877 for ( unsigned int i = 0; i < aCoordLists.size(); i++ )
878 aBezierCoords.Coordinates[i] = ContainerHelper::vectorToSequence( aCoordLists[i] );
880 aBezierCoords.Flags.realloc( aFlagLists.size() );
881 for ( unsigned int i = 0; i < aFlagLists.size(); i++ )
882 aBezierCoords.Flags[i] = ContainerHelper::vectorToSequence( aFlagLists[i] );
884 if( !aCoordLists.front().empty() && !aCoordLists.back().empty()
885 && aCoordLists.front().front().X == aCoordLists.back().back().X
886 && aCoordLists.front().front().Y == aCoordLists.back().back().Y )
887 { // HACK: If the shape is in fact closed, which can be found out only when the path is known,
888 // force to closed bezier shape (otherwise e.g. fill won't work).
889 const_cast< BezierShape* >( this )->setService( "com.sun.star.drawing.ClosedBezierShape" );
893 Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
895 if( aBezierCoords.Coordinates.hasElements())
897 PropertySet aPropSet( xShape );
898 aPropSet.setProperty( PROP_PolyPolygonBezier, aBezierCoords );
901 // Hacky way of ensuring the shape is correctly sized/positioned
902 xShape->setSize( awt::Size( rShapeRect.Width, rShapeRect.Height ) );
903 xShape->setPosition( awt::Point( rShapeRect.X, rShapeRect.Y ) );
904 return xShape;
907 // ============================================================================
909 CustomShape::CustomShape( Drawing& rDrawing ) :
910 SimpleShape( rDrawing, "com.sun.star.drawing.CustomShape" )
914 Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
916 // try to create a custom shape
917 Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
918 if( xShape.is() ) try
920 // create the custom shape geometry
921 Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
922 xDefaulter->createCustomShapeDefaults( OUString::number( getShapeType() ) );
923 // convert common properties
924 convertShapeProperties( xShape );
926 catch( Exception& )
929 return xShape;
932 // ============================================================================
934 ComplexShape::ComplexShape( Drawing& rDrawing ) :
935 CustomShape( rDrawing )
939 Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
941 XmlFilterBase& rFilter = mrDrawing.getFilter();
942 sal_Int32 nShapeType = getShapeType();
943 OUString aGraphicPath = getGraphicPath();
945 // try to find registered OLE object info
946 if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
948 SAL_WARN_IF(
949 nShapeType != VML_SHAPETYPE_PICTUREFRAME, "oox",
950 "ComplexShape::implConvertAndInsert - unexpected shape type");
952 // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
953 if( pOleObjectInfo->mbDmlShape )
954 return Reference< XShape >();
956 PropertyMap aOleProps;
957 awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
958 if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
960 Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.OLE2Shape", rxShapes, rShapeRect );
961 if( xShape.is() )
963 // set the replacement graphic
964 if( !aGraphicPath.isEmpty() )
966 Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
967 if( xGraphic.is() )
968 aOleProps[ PROP_Graphic ] <<= xGraphic;
971 PropertySet aPropSet( xShape );
972 aPropSet.setProperties( aOleProps );
974 return xShape;
979 // try to find registered form control info
980 const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
981 if( pControlInfo && !pControlInfo->maFragmentPath.isEmpty() )
983 OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
984 OUString aShapeName = getShapeName();
985 if( !aShapeName.isEmpty() )
987 OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
988 // load the control properties from fragment
989 ::oox::ole::EmbeddedControl aControl( aShapeName );
990 if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
992 // create and return the control shape (including control model)
993 sal_Int32 nCtrlIndex = -1;
994 Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
995 // on error, proceed and try to create picture from replacement image
996 if( xShape.is() )
997 return xShape;
1002 // host application wants to create the shape (do not try failed OLE controls again)
1003 if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo )
1005 OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" );
1006 Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect );
1007 if( xShape.is() )
1008 return xShape;
1011 // try to create a picture object
1012 if( !aGraphicPath.isEmpty() )
1013 return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
1015 // default: try to create a custom shape
1016 return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
1019 // ============================================================================
1021 GroupShape::GroupShape( Drawing& rDrawing ) :
1022 ShapeBase( rDrawing ),
1023 mxChildren( new ShapeContainer( rDrawing ) )
1027 GroupShape::~GroupShape()
1031 void GroupShape::finalizeFragmentImport()
1033 // basic shape processing
1034 ShapeBase::finalizeFragmentImport();
1035 // finalize all child shapes
1036 mxChildren->finalizeFragmentImport();
1039 const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
1041 return mxChildren->getShapeTypeById( rShapeId, true );
1044 const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
1046 return mxChildren->getShapeById( rShapeId, true );
1049 Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
1051 Reference< XShape > xGroupShape;
1052 // check that this shape contains children and a valid coordinate system
1053 ShapeParentAnchor aParentAnchor;
1054 aParentAnchor.maShapeRect = rShapeRect;
1055 aParentAnchor.maCoordSys = getCoordSystem();
1056 if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
1058 xGroupShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GroupShape", rxShapes, rShapeRect );
1059 Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
1060 mxChildren->convertAndInsert( xChildShapes, &aParentAnchor );
1061 if( !xChildShapes->hasElements() )
1063 SAL_WARN("oox", "no child shape has been created - deleting the group shape");
1064 rxShapes->remove( xGroupShape );
1065 xGroupShape.clear();
1068 catch( Exception& )
1071 // Make sure group shapes are inline as well, unless there is an explicit different style.
1072 PropertySet aPropertySet(xGroupShape);
1073 lcl_SetAnchorType(aPropertySet, maTypeModel);
1074 if (!maTypeModel.maRotation.isEmpty())
1075 lcl_SetRotation(aPropertySet, maTypeModel.maRotation.toInt32());
1076 return xGroupShape;
1079 // ============================================================================
1081 } // namespace vml
1082 } // namespace oox
1084 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */