LCOV - code coverage report
Current view: top level - libreoffice/oox/source/vml - vmlshape.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 322 398 80.9 %
Date: 2012-12-27 Functions: 49 53 92.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <algorithm>
      21             : 
      22             : #include "oox/vml/vmlshape.hxx"
      23             : 
      24             : #include <com/sun/star/beans/PropertyValues.hpp>
      25             : #include <com/sun/star/beans/XPropertySet.hpp>
      26             : #include <com/sun/star/awt/XControlModel.hpp>
      27             : #include <com/sun/star/drawing/PointSequenceSequence.hpp>
      28             : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
      29             : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
      30             : #include <com/sun/star/drawing/XShapes.hpp>
      31             : #include <com/sun/star/drawing/XControlShape.hpp>
      32             : #include <com/sun/star/graphic/XGraphic.hpp>
      33             : #include <com/sun/star/text/HoriOrientation.hpp>
      34             : #include <com/sun/star/text/RelOrientation.hpp>
      35             : #include <com/sun/star/text/SizeType.hpp>
      36             : #include <com/sun/star/text/VertOrientation.hpp>
      37             : #include <com/sun/star/text/XTextContent.hpp>
      38             : #include <com/sun/star/text/XTextDocument.hpp>
      39             : #include <com/sun/star/text/XTextFrame.hpp>
      40             : #include <com/sun/star/text/TextContentAnchorType.hpp>
      41             : #include <rtl/math.hxx>
      42             : #include <rtl/ustrbuf.hxx>
      43             : #include "oox/drawingml/shapepropertymap.hxx"
      44             : #include "oox/helper/graphichelper.hxx"
      45             : #include "oox/helper/propertyset.hxx"
      46             : #include "oox/ole/axcontrol.hxx"
      47             : #include "oox/ole/axcontrolfragment.hxx"
      48             : #include "oox/ole/oleobjecthelper.hxx"
      49             : #include "oox/vml/vmldrawing.hxx"
      50             : #include "oox/vml/vmlshapecontainer.hxx"
      51             : #include "oox/vml/vmltextbox.hxx"
      52             : #include "oox/core/xmlfilterbase.hxx"
      53             : #include "oox/helper/containerhelper.hxx"
      54             : 
      55             : using ::com::sun::star::beans::XPropertySet;
      56             : using ::com::sun::star::uno::Any;
      57             : 
      58             : using namespace ::com::sun::star;
      59             : using namespace ::com::sun::star::text;
      60             : 
      61             : namespace oox {
      62             : namespace vml {
      63             : 
      64             : // ============================================================================
      65             : 
      66             : using namespace ::com::sun::star;
      67             : using namespace ::com::sun::star::drawing;
      68             : using namespace ::com::sun::star::graphic;
      69             : using namespace ::com::sun::star::uno;
      70             : using namespace ::com::sun::star::io;
      71             : 
      72             : using ::oox::core::XmlFilterBase;
      73             : using ::rtl::OUString;
      74             : using ::rtl::OUStringBuffer;
      75             : 
      76             : // ============================================================================
      77             : 
      78             : namespace {
      79             : 
      80             : const sal_Int32 VML_SHAPETYPE_PICTUREFRAME  = 75;
      81             : const sal_Int32 VML_SHAPETYPE_HOSTCONTROL   = 201;
      82             : 
      83             : // ----------------------------------------------------------------------------
      84             : 
      85          96 : awt::Point lclGetAbsPoint( const awt::Point& rRelPoint, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
      86             : {
      87          96 :     double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
      88          96 :     double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
      89          96 :     awt::Point aAbsPoint;
      90          96 :     aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
      91          96 :     aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
      92          96 :     return aAbsPoint;
      93             : }
      94             : 
      95           8 : awt::Rectangle lclGetAbsRect( const awt::Rectangle& rRelRect, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
      96             : {
      97           8 :     double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
      98           8 :     double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
      99           8 :     awt::Rectangle aAbsRect;
     100           8 :     aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
     101           8 :     aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
     102           8 :     aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
     103           8 :     aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
     104           8 :     return aAbsRect;
     105             : }
     106             : 
     107             : } // namespace
     108             : 
     109             : // ============================================================================
     110             : 
     111          43 : ShapeTypeModel::ShapeTypeModel():
     112             :     mbAutoHeight( sal_False ),
     113          43 :     mbVisible( sal_True )
     114             : {
     115          43 : }
     116             : 
     117          11 : void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
     118             : {
     119          11 :     moShapeType.assignIfUsed( rSource.moShapeType );
     120          11 :     moCoordPos.assignIfUsed( rSource.moCoordPos );
     121          11 :     moCoordSize.assignIfUsed( rSource.moCoordSize );
     122             :     /*  The style properties position, left, top, width, height, margin-left,
     123             :         margin-top are not derived from shape template to shape. */
     124          11 :     maStrokeModel.assignUsed( rSource.maStrokeModel );
     125          11 :     maFillModel.assignUsed( rSource.maFillModel );
     126          11 :     moGraphicPath.assignIfUsed( rSource.moGraphicPath );
     127          11 :     moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
     128          11 : }
     129             : 
     130             : // ----------------------------------------------------------------------------
     131             : 
     132          43 : ShapeType::ShapeType( Drawing& rDrawing ) :
     133          43 :     mrDrawing( rDrawing )
     134             : {
     135          43 : }
     136             : 
     137          55 : ShapeType::~ShapeType()
     138             : {
     139          55 : }
     140             : 
     141          15 : sal_Int32 ShapeType::getShapeType() const
     142             : {
     143          15 :     return maTypeModel.moShapeType.get( 0 );
     144             : }
     145             : 
     146          22 : OUString ShapeType::getGraphicPath() const
     147             : {
     148          22 :     return maTypeModel.moGraphicPath.get( OUString() );
     149             : }
     150             : 
     151           6 : awt::Rectangle ShapeType::getCoordSystem() const
     152             : {
     153           6 :     Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) );
     154           6 :     Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) );
     155           6 :     return awt::Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second );
     156             : }
     157             : 
     158          29 : awt::Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
     159             : {
     160             :     return pParentAnchor ?
     161          37 :         lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
     162          66 :         getAbsRectangle();
     163             : }
     164             : 
     165          21 : awt::Rectangle ShapeType::getAbsRectangle() const
     166             : {
     167          21 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     168             : 
     169          21 :     sal_Int32 nWidth = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true );
     170          21 :     if ( nWidth == 0 )
     171           2 :         nWidth = 1;
     172             : 
     173          21 :     sal_Int32 nHeight = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true );
     174          21 :     if ( nHeight == 0 )
     175           1 :         nHeight = 1;
     176             : 
     177          21 :     sal_Int32 nLeft = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true )
     178          21 :         + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true );
     179          21 :     if (nLeft == 0 && maTypeModel.maPosition == "absolute")
     180          10 :         nLeft = 1;
     181             : 
     182             :     return awt::Rectangle(
     183             :         nLeft,
     184          21 :         ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ),
     185          21 :         nWidth, nHeight );
     186             : }
     187             : 
     188           8 : awt::Rectangle ShapeType::getRelRectangle() const
     189             : {
     190             :     return awt::Rectangle(
     191           8 :         maTypeModel.maLeft.toInt32(),
     192           8 :         maTypeModel.maTop.toInt32(),
     193           8 :         maTypeModel.maWidth.toInt32(),
     194          32 :         maTypeModel.maHeight.toInt32() );
     195             : }
     196             : 
     197             : // ============================================================================
     198             : 
     199           2 : ClientData::ClientData() :
     200             :     mnObjType( XML_TOKEN_INVALID ),
     201             :     mnTextHAlign( XML_Left ),
     202             :     mnTextVAlign( XML_Top ),
     203             :     mnCol( -1 ),
     204             :     mnRow( -1 ),
     205             :     mnChecked( VML_CLIENTDATA_UNCHECKED ),
     206             :     mnDropStyle( XML_Combo ),
     207             :     mnDropLines( 1 ),
     208             :     mnVal( 0 ),
     209             :     mnMin( 0 ),
     210             :     mnMax( 0 ),
     211             :     mnInc( 0 ),
     212             :     mnPage( 0 ),
     213             :     mnSelType( XML_Single ),
     214             :     mnVTEdit( VML_CLIENTDATA_TEXT ),
     215             :     mbPrintObject( true ),
     216             :     mbVisible( false ),
     217             :     mbDde( false ),
     218             :     mbNo3D( false ),
     219             :     mbNo3D2( false ),
     220             :     mbMultiLine( false ),
     221             :     mbVScroll( false ),
     222           2 :     mbSecretEdit( false )
     223             : {
     224           2 : }
     225             : 
     226             : // ----------------------------------------------------------------------------
     227             : 
     228          31 : ShapeModel::ShapeModel()
     229             : {
     230          31 : }
     231             : 
     232          31 : ShapeModel::~ShapeModel()
     233             : {
     234          31 : }
     235             : 
     236          15 : TextBox& ShapeModel::createTextBox(ShapeTypeModel& rModel)
     237             : {
     238          15 :     mxTextBox.reset( new TextBox(rModel) );
     239          15 :     return *mxTextBox;
     240             : }
     241             : 
     242           2 : ClientData& ShapeModel::createClientData()
     243             : {
     244           2 :     mxClientData.reset( new ClientData );
     245           2 :     return *mxClientData;
     246             : }
     247             : 
     248             : // ----------------------------------------------------------------------------
     249             : 
     250          31 : ShapeBase::ShapeBase( Drawing& rDrawing ) :
     251          31 :     ShapeType( rDrawing )
     252             : {
     253          31 : }
     254             : 
     255          31 : void ShapeBase::finalizeFragmentImport()
     256             : {
     257             :     // resolve shape template reference
     258          31 :     if( (maShapeModel.maType.getLength() > 1) && (maShapeModel.maType[ 0 ] == '#') )
     259          15 :         if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( maShapeModel.maType.copy( 1 ), true ) )
     260          11 :             maTypeModel.assignUsed( pShapeType->getTypeModel() );
     261          31 : }
     262             : 
     263          22 : OUString ShapeBase::getShapeName() const
     264             : {
     265          22 :     if( !maTypeModel.maShapeName.isEmpty() )
     266           3 :         return maTypeModel.maShapeName;
     267             : 
     268          19 :     OUString aBaseName = mrDrawing.getShapeBaseName( *this );
     269          19 :     if( !aBaseName.isEmpty() )
     270             :     {
     271           1 :         sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() );
     272           1 :         if( nShapeIdx > 0 )
     273           1 :             return OUStringBuffer( aBaseName ).append( sal_Unicode( ' ' ) ).append( nShapeIdx ).makeStringAndClear();
     274             :     }
     275             : 
     276          18 :     return OUString();
     277             : }
     278             : 
     279           6 : const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
     280             : {
     281           6 :     return 0;
     282             : }
     283             : 
     284           0 : const ShapeBase* ShapeBase::getChildById( const OUString& ) const
     285             : {
     286           0 :     return 0;
     287             : }
     288             : 
     289          31 : Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
     290             : {
     291          31 :     Reference< XShape > xShape;
     292          31 :     if( mrDrawing.isShapeSupported( *this ) )
     293             :     {
     294             :         /*  Calculate shape rectangle. Applications may do something special
     295             :             according to some imported shape client data (e.g. Excel cell anchor). */
     296          30 :         awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
     297             : 
     298             :         // convert the shape, if the calculated rectangle is not empty
     299          30 :         if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
     300             :         {
     301          30 :             xShape = implConvertAndInsert( rxShapes, aShapeRect );
     302          30 :             if( xShape.is() )
     303             :             {
     304             :                 // set imported or generated shape name (not supported by form controls)
     305          30 :                 PropertySet aShapeProp( xShape );
     306          30 :                 if( aShapeProp.hasProperty( PROP_Name ) )
     307          21 :                     aShapeProp.setProperty( PROP_Name, getShapeName() );
     308          30 :                 Reference< XControlShape > xControlShape( xShape, uno::UNO_QUERY );
     309          30 :                 if ( xControlShape.is() && !getTypeModel().mbVisible )
     310             :                 {
     311           0 :                     PropertySet aControlShapeProp( xControlShape->getControl() );
     312           0 :                     aControlShapeProp.setProperty( PROP_EnableVisible, uno::makeAny( sal_False ) );
     313             :                 }
     314             :                 /*  Notify the drawing that a new shape has been inserted. For
     315             :                     convenience, pass the rectangle that contains position and
     316             :                     size of the shape. */
     317          30 :                 bool bGroupChild = pParentAnchor != 0;
     318          30 :                 mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild );
     319             :             }
     320             :         }
     321             :     }
     322          31 :     return xShape;
     323             : }
     324             : 
     325           1 : void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const
     326             : {
     327           1 :     if( rxShape.is() )
     328             :     {
     329             :         /*  Calculate shape rectangle. Applications may do something special
     330             :             according to some imported shape client data (e.g. Excel cell anchor). */
     331           1 :         awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
     332             : 
     333             :         // convert the shape, if the calculated rectangle is not empty
     334           1 :         if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
     335             :         {
     336           1 :             rxShape->setPosition( awt::Point( aShapeRect.X, aShapeRect.Y ) );
     337           1 :             rxShape->setSize( awt::Size( aShapeRect.Width, aShapeRect.Height ) );
     338           1 :             convertShapeProperties( rxShape );
     339             :         }
     340             :     }
     341           1 : }
     342             : 
     343             : // protected ------------------------------------------------------------------
     344             : 
     345          31 : awt::Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
     346             : {
     347             :     /*  Calculate shape rectangle. Applications may do something special
     348             :         according to some imported shape client data (e.g. Excel cell anchor). */
     349          31 :     awt::Rectangle aShapeRect;
     350          31 :     const ClientData* pClientData = getClientData();
     351          31 :     if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) )
     352          29 :         aShapeRect = getRectangle( pParentAnchor );
     353          31 :     return aShapeRect;
     354             : }
     355             : 
     356          18 : void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
     357             : {
     358          18 :     ::oox::drawingml::ShapePropertyMap aPropMap( mrDrawing.getFilter().getModelObjectHelper() );
     359          18 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     360          18 :     maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper );
     361          18 :     maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper );
     362             : 
     363             :     // TextFrames have FillColor, not BackColor
     364          18 :     uno::Reference<lang::XServiceInfo> xSInfo(rxShape, uno::UNO_QUERY_THROW);
     365          18 :     if (xSInfo->supportsService("com.sun.star.text.TextFrame") && aPropMap.hasProperty(PROP_FillColor))
     366             :     {
     367           4 :         aPropMap.setProperty(PROP_BackColor, aPropMap[PROP_FillColor]);
     368           4 :         aPropMap.erase(PROP_FillColor);
     369             :     }
     370             : 
     371          18 :     PropertySet( rxShape ).setProperties( aPropMap );
     372          18 : }
     373             : 
     374             : // ============================================================================
     375             : 
     376          26 : SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :
     377             :     ShapeBase( rDrawing ),
     378          26 :     maService( rService )
     379             : {
     380          26 : }
     381             : 
     382          29 : void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
     383             : {
     384          29 :     if ( rTypeModel.maPositionHorizontal == "center" )
     385           6 :         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));
     386             : 
     387          29 :     if ( rTypeModel.maPositionHorizontalRelative == "page" )
     388           3 :         rPropSet.setAnyProperty(PROP_HoriOrientRelation, makeAny(text::RelOrientation::PAGE_FRAME));
     389             : 
     390          29 :     if ( rTypeModel.maPositionVertical == "center" )
     391           2 :         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::CENTER));
     392             : 
     393          29 :     if ( rTypeModel.maPosition == "absolute" )
     394             :     {
     395          26 :         if (rTypeModel.moWrapAnchorX.get() == "page" && rTypeModel.moWrapAnchorY.get() == "page")
     396             :         {
     397             :             // I'm not sure if AT_PAGE is always correct here (not sure what the parent that
     398             :             // the spec talks about can be), but with Writer SwXDrawPage::add()
     399             :             // always in practice uses this because of pDoc->GetCurrentLayout() being NULL at this point.
     400           2 :             rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PAGE);
     401             :         }
     402             :         else
     403             :         {
     404             :             // Map to as-character by default, that fixes vertical position of some textframes.
     405          24 :             rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
     406             :         }
     407             : 
     408          26 :         if ( rTypeModel.maPositionVerticalRelative == "page" )
     409             :         {
     410           2 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
     411             :         }
     412             :         else
     413             :         {
     414             :             // Vertical placement relative to margin, because parent style must not modify vertical position
     415          24 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
     416             :         }
     417             :     }
     418           3 :     else if( rTypeModel.maPosition == "relative" )
     419             :     {   // I'm not very sure this is correct either.
     420           0 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PARAGRAPH);
     421             :     }
     422             :     else // static (is the default) means anchored inline
     423             :     {
     424           3 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AS_CHARACTER);
     425             :     }
     426          29 : }
     427             : 
     428          16 : Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     429             : {
     430          16 :     awt::Rectangle aShapeRect(rShapeRect);
     431          16 :     if (!maTypeModel.maFlip.isEmpty())
     432             :     {
     433           1 :         if (maTypeModel.maFlip.equalsAscii("x"))
     434             :         {
     435           1 :             aShapeRect.X += aShapeRect.Width;
     436           1 :             aShapeRect.Width *= -1;
     437             :         }
     438           0 :         else if (maTypeModel.maFlip.equalsAscii("y"))
     439             :         {
     440           0 :             aShapeRect.Y += aShapeRect.Height;
     441           0 :             aShapeRect.Height *= -1;
     442             :         }
     443             :     }
     444             : 
     445          16 :     Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, aShapeRect );
     446          16 :     convertShapeProperties( xShape );
     447             : 
     448          16 :     if ( maService.equalsAscii( "com.sun.star.text.TextFrame" ) )
     449             :     {
     450           8 :         PropertySet( xShape ).setAnyProperty( PROP_FrameIsAutomaticHeight, makeAny( maTypeModel.mbAutoHeight ) );
     451           8 :         PropertySet( xShape ).setAnyProperty( PROP_SizeType, makeAny( maTypeModel.mbAutoHeight ? SizeType::MIN : SizeType::FIX ) );
     452           8 :         if( getTextBox()->borderDistanceSet )
     453             :         {
     454           8 :             PropertySet( xShape ).setAnyProperty( PROP_LeftBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceLeft )));
     455           8 :             PropertySet( xShape ).setAnyProperty( PROP_TopBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceTop )));
     456           8 :             PropertySet( xShape ).setAnyProperty( PROP_RightBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceRight )));
     457           8 :             PropertySet( xShape ).setAnyProperty( PROP_BottomBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceBottom )));
     458             :         }
     459             :     }
     460             :     else
     461             :     {
     462             :         // FIXME Setting the relative width/heigh only for everything but text frames as
     463             :         // TextFrames already have relative widht/heigh feature... but currently not working
     464             :         // in the way we need.
     465             : 
     466             :         // Set the relative width / height if any
     467           8 :         if ( !maTypeModel.maWidthPercent.isEmpty( ) )
     468             :         {
     469             :             // Only page-relative width is supported ATM
     470           3 :             if ( maTypeModel.maWidthRelative.isEmpty() || maTypeModel.maWidthRelative == "page" )
     471             :             {
     472           1 :                 sal_Int16 nWidth = maTypeModel.maWidthPercent.toInt32() / 10;
     473             :                 // Only apply if nWidth != 0
     474           1 :                 if ( nWidth )
     475           1 :                     PropertySet( xShape ).setAnyProperty(PROP_RelativeWidth, makeAny( nWidth ) );
     476             :             }
     477             :         }
     478           8 :         if ( !maTypeModel.maHeightPercent.isEmpty( ) )
     479             :         {
     480             :             // Only page-relative height is supported ATM
     481           1 :             if ( maTypeModel.maHeightRelative.isEmpty() || maTypeModel.maHeightRelative == "page" )
     482             :             {
     483           1 :                 sal_Int16 nHeight = maTypeModel.maHeightPercent.toInt32() / 10;
     484             :                 // Only apply if nHeight != 0
     485           1 :                 if ( nHeight )
     486           1 :                     PropertySet( xShape ).setAnyProperty(PROP_RelativeHeight, makeAny( nHeight ) );
     487             :             }
     488             :         }
     489             : 
     490           8 :         if (getTextBox())
     491           3 :             getTextBox()->convert(xShape);
     492             :     }
     493             : 
     494             :     // Import Legacy Fragments (if any)
     495          16 :     if( xShape.is() && !maShapeModel.maLegacyDiagramPath.isEmpty() )
     496             :     {
     497           0 :         Reference< XInputStream > xInStrm( mrDrawing.getFilter().openInputStream( maShapeModel.maLegacyDiagramPath ), UNO_SET_THROW );
     498           0 :         if( xInStrm.is() )
     499           0 :             PropertySet( xShape ).setProperty( PROP_LegacyFragment, xInStrm );
     500             :     }
     501             : 
     502          16 :     PropertySet aPropertySet(xShape);
     503          16 :     if (xShape.is() && !maTypeModel.maRotation.isEmpty())
     504             :     {
     505           1 :         aPropertySet.setAnyProperty(PROP_RotateAngle, makeAny(maTypeModel.maRotation.toInt32() * 100));
     506             :         // If rotation is used, simple setPosition() is not enough.
     507           1 :         aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) );
     508           1 :         aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) );
     509             :     }
     510             : 
     511          16 :     lcl_SetAnchorType(aPropertySet, maTypeModel);
     512             : 
     513          16 :     return xShape;
     514             : }
     515             : 
     516           8 : Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString& rGraphicPath ) const
     517             : {
     518           8 :     Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GraphicObjectShape", rxShapes, rShapeRect );
     519           8 :     if( xShape.is() )
     520             :     {
     521           8 :         XmlFilterBase& rFilter = mrDrawing.getFilter();
     522           8 :         OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( rGraphicPath );
     523           8 :         PropertySet aPropSet( xShape );
     524           8 :         if( !aGraphicUrl.isEmpty() )
     525             :         {
     526           8 :             aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
     527             :         }
     528           8 :         uno::Reference< lang::XServiceInfo > xServiceInfo(rxShapes, uno::UNO_QUERY);
     529             :         // If the shape has an absolute position, set the properties accordingly, unless we're inside a group shape.
     530           8 :         if ( maTypeModel.maPosition == "absolute" && !xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
     531             :         {
     532           3 :             aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
     533           3 :             aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
     534           3 :             aPropSet.setProperty(PROP_Opaque, sal_False);
     535             :         }
     536             : 
     537           8 :         lcl_SetAnchorType(aPropSet, maTypeModel);
     538             :     }
     539           8 :     return xShape;
     540             : }
     541             : 
     542             : // ============================================================================
     543             : 
     544           8 : RectangleShape::RectangleShape( Drawing& rDrawing ) :
     545           8 :     SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ) )
     546             : {
     547           8 : }
     548             : 
     549           8 : Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const awt::Rectangle& rShapeRect) const
     550             : {
     551           8 :     OUString aGraphicPath = getGraphicPath();
     552             : 
     553             :     // try to create a picture object
     554           8 :     if(!aGraphicPath.isEmpty())
     555           1 :         return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
     556             : 
     557             :     // default: try to create a rectangle shape
     558           7 :     Reference<XShape> xShape = SimpleShape::implConvertAndInsert(rxShapes, rShapeRect);
     559           7 :     rtl::OUString sArcsize = maTypeModel.maArcsize;
     560           7 :     if ( !sArcsize.isEmpty( ) )
     561             :     {
     562           1 :         sal_Unicode cLastChar = sArcsize[sArcsize.getLength() - 1];
     563           1 :         sal_Int32 nValue = sArcsize.copy( 0, sArcsize.getLength() - 1 ).toInt32( );
     564             :         // Get the smallest half-side
     565           1 :         double size = std::min( rShapeRect.Height, rShapeRect.Width ) / 2.0;
     566           1 :         sal_Int32 nRadius = 0;
     567           1 :         if ( cLastChar == 'f' )
     568           1 :             nRadius = size * nValue / 65536;
     569           0 :         else if ( cLastChar == '%' )
     570           0 :             nRadius = size * nValue / 100;
     571           1 :         PropertySet( xShape ).setAnyProperty( PROP_CornerRadius, makeAny( nRadius ) );
     572             :     }
     573           7 :     return xShape;
     574             : }
     575             : 
     576             : // ============================================================================
     577             : 
     578           1 : EllipseShape::EllipseShape( Drawing& rDrawing ) :
     579           1 :     SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ) )
     580             : {
     581           1 : }
     582             : 
     583             : // ============================================================================
     584             : 
     585           0 : PolyLineShape::PolyLineShape( Drawing& rDrawing ) :
     586           0 :     SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ) )
     587             : {
     588           0 : }
     589             : 
     590           0 : Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     591             : {
     592           0 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     593             :     // polygon path
     594           0 :     awt::Rectangle aCoordSys = getCoordSystem();
     595           0 :     if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
     596             :     {
     597           0 :         ::std::vector< awt::Point > aAbsPoints;
     598           0 :         for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
     599           0 :             aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
     600           0 :         PointSequenceSequence aPointSeq( 1 );
     601           0 :         aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
     602           0 :         PropertySet aPropSet( xShape );
     603           0 :         aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
     604             :     }
     605           0 :     return xShape;
     606             : }
     607             : 
     608           1 : LineShape::LineShape(Drawing& rDrawing)
     609           1 :     : SimpleShape(rDrawing, "com.sun.star.drawing.LineShape")
     610             : {
     611           1 : }
     612             : 
     613           1 : Reference<XShape> LineShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const awt::Rectangle& rShapeRect) const
     614             : {
     615           1 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     616           1 :     awt::Rectangle aShapeRect(rShapeRect);
     617           1 :     sal_Int32 nIndex = 0;
     618             : 
     619           1 :     aShapeRect.X = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, true, true);
     620           1 :     aShapeRect.Y = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, false, true);
     621           1 :     nIndex = 0;
     622           1 :     aShapeRect.Width = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, true, true) - aShapeRect.X;
     623           1 :     aShapeRect.Height = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, false, true) - aShapeRect.Y;
     624             : 
     625           1 :     return SimpleShape::implConvertAndInsert(rxShapes, aShapeRect);
     626             : }
     627             : 
     628             : // ============================================================================
     629             : 
     630           1 : BezierShape::BezierShape(Drawing& rDrawing)
     631           1 :     : SimpleShape(rDrawing, "com.sun.star.drawing.OpenBezierShape")
     632             : {
     633           1 : }
     634             : 
     635           1 : Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     636             : {
     637           1 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     638           1 :     awt::Rectangle aCoordSys = getCoordSystem();
     639             : 
     640           1 :     if( (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
     641             :     {
     642           1 :         const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     643             : 
     644             :         // Bezier paths may consist of one or more sub-paths
     645             :         typedef ::std::vector< ::std::vector< awt::Point > > SubPathList;
     646             :         typedef ::std::vector< ::std::vector< PolygonFlags > > FlagsList;
     647           1 :         SubPathList aCoordLists;
     648           1 :         FlagsList aFlagLists;
     649           1 :         sal_Int32 nIndex = 0;
     650             : 
     651             :         // Curve defined by to, from, control1 and control2 attributes
     652           1 :         if ( maShapeModel.maVmlPath.isEmpty() )
     653             :         {
     654           0 :             aCoordLists.push_back( ::std::vector< awt::Point >() );
     655           0 :             aFlagLists.push_back( ::std::vector< PolygonFlags >() );
     656             : 
     657             :             // Start point
     658           0 :             aCoordLists[ 0 ].push_back(
     659           0 :                 awt::Point(ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, true, true ),
     660           0 :                   ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     661             :             // Control point 1
     662           0 :             aCoordLists[ 0 ].push_back(
     663           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, true, true ),
     664           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     665             :             // Control point 2
     666           0 :             aCoordLists[ 0 ].push_back(
     667           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, true, true ),
     668           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     669             :             // End point
     670           0 :             aCoordLists[ 0 ].push_back(
     671           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, true, true ),
     672           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     673             : 
     674             :             // First and last points are normals, points 2 and 4 are controls
     675           0 :             aFlagLists[ 0 ].resize( aCoordLists[ 0 ].size(), PolygonFlags_CONTROL );
     676           0 :             aFlagLists[ 0 ][ 0 ] = PolygonFlags_NORMAL;
     677           0 :             aFlagLists[ 0 ].back() = PolygonFlags_NORMAL;
     678             :         }
     679             :         // Curve defined by path attribute
     680             :         else
     681             :         {
     682             :             // Parse VML path string and convert to absolute coordinates
     683           1 :             ConversionHelper::decodeVmlPath( aCoordLists, aFlagLists, maShapeModel.maVmlPath );
     684             : 
     685           4 :             for ( SubPathList::iterator aListIt = aCoordLists.begin(); aListIt != aCoordLists.end(); ++aListIt )
     686          99 :                 for ( ::std::vector< awt::Point >::iterator aPointIt = (*aListIt).begin(); aPointIt != (*aListIt).end(); ++aPointIt)
     687             :                 {
     688          96 :                     (*aPointIt) = lclGetAbsPoint( (*aPointIt), rShapeRect, aCoordSys );
     689             :                 }
     690             :         }
     691             : 
     692           1 :         PolyPolygonBezierCoords aBezierCoords;
     693           1 :         aBezierCoords.Coordinates.realloc( aCoordLists.size() );
     694           4 :         for ( unsigned int i = 0; i < aCoordLists.size(); i++ )
     695           3 :             aBezierCoords.Coordinates[i] = ContainerHelper::vectorToSequence( aCoordLists[i] );
     696             : 
     697           1 :         aBezierCoords.Flags.realloc( aFlagLists.size() );
     698           4 :         for ( unsigned int i = 0; i < aFlagLists.size(); i++ )
     699           3 :             aBezierCoords.Flags[i] = ContainerHelper::vectorToSequence( aFlagLists[i] );
     700             : 
     701           1 :         PropertySet aPropSet( xShape );
     702           1 :         aPropSet.setProperty( PROP_PolyPolygonBezier, aBezierCoords );
     703             :     }
     704             : 
     705             :     // Hacky way of ensuring the shape is correctly sized/positioned
     706           1 :     xShape->setSize( awt::Size( rShapeRect.Width, rShapeRect.Height ) );
     707           1 :     xShape->setPosition( awt::Point( rShapeRect.X, rShapeRect.Y ) );
     708           1 :     return xShape;
     709             : }
     710             : 
     711             : // ============================================================================
     712             : 
     713          15 : CustomShape::CustomShape( Drawing& rDrawing ) :
     714          15 :     SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.CustomShape" ) )
     715             : {
     716          15 : }
     717             : 
     718           6 : Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     719             : {
     720             :     // try to create a custom shape
     721           6 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     722           6 :     if( xShape.is() ) try
     723             :     {
     724             :         // create the custom shape geometry
     725           6 :         Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
     726           1 :         xDefaulter->createCustomShapeDefaults( OUString::valueOf( getShapeType() ) );
     727             :         // convert common properties
     728           1 :         convertShapeProperties( xShape );
     729             :     }
     730           5 :     catch( Exception& )
     731             :     {
     732             :     }
     733           6 :     return xShape;
     734             : }
     735             : 
     736             : // ============================================================================
     737             : 
     738          15 : ComplexShape::ComplexShape( Drawing& rDrawing ) :
     739          15 :     CustomShape( rDrawing )
     740             : {
     741          15 : }
     742             : 
     743          14 : Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     744             : {
     745          14 :     XmlFilterBase& rFilter = mrDrawing.getFilter();
     746          14 :     sal_Int32 nShapeType = getShapeType();
     747          14 :     OUString aGraphicPath = getGraphicPath();
     748             : 
     749             :     // try to find registered OLE object info
     750          14 :     if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
     751             :     {
     752             :         OSL_ENSURE( nShapeType == VML_SHAPETYPE_PICTUREFRAME, "ComplexShape::implConvertAndInsert - unexpected shape type" );
     753             : 
     754             :         // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
     755           0 :         if( pOleObjectInfo->mbDmlShape )
     756           0 :             return Reference< XShape >();
     757             : 
     758           0 :         PropertyMap aOleProps;
     759           0 :         awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
     760           0 :         if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
     761             :         {
     762           0 :             Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rxShapes, rShapeRect );
     763           0 :             if( xShape.is() )
     764             :             {
     765             :                 // set the replacement graphic
     766           0 :                 if( !aGraphicPath.isEmpty() )
     767             :                 {
     768           0 :                     Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
     769           0 :                     if( xGraphic.is() )
     770           0 :                         aOleProps[ PROP_Graphic ] <<= xGraphic;
     771             :                 }
     772             : 
     773           0 :                 PropertySet aPropSet( xShape );
     774           0 :                 aPropSet.setProperties( aOleProps );
     775             : 
     776           0 :                 return xShape;
     777           0 :             }
     778           0 :         }
     779             :     }
     780             : 
     781             :     // try to find registered form control info
     782          14 :     const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
     783          14 :     if( pControlInfo && !pControlInfo->maFragmentPath.isEmpty() )
     784             :     {
     785             :         OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
     786           0 :         OUString aShapeName = getShapeName();
     787           0 :         if( !aShapeName.isEmpty() )
     788             :         {
     789             :             OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
     790             :             // load the control properties from fragment
     791           0 :             ::oox::ole::EmbeddedControl aControl( aShapeName );
     792           0 :             if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
     793             :             {
     794             :                 // create and return the control shape (including control model)
     795           0 :                 sal_Int32 nCtrlIndex = -1;
     796           0 :                 Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
     797             :                 // on error, proceed and try to create picture from replacement image
     798           0 :                 if( xShape.is() )
     799           0 :                     return xShape;
     800           0 :             }
     801           0 :         }
     802             :     }
     803             : 
     804             :     // host application wants to create the shape (do not try failed OLE controls again)
     805          14 :     if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo )
     806             :     {
     807             :         OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" );
     808           1 :         Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect );
     809           1 :         if( xShape.is() )
     810           1 :             return xShape;
     811             :     }
     812             : 
     813             :     // try to create a picture object
     814          13 :     if( !aGraphicPath.isEmpty() )
     815           7 :         return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
     816             : 
     817             :     // default: try to create a custom shape
     818           6 :     return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
     819             : }
     820             : 
     821             : // ============================================================================
     822             : 
     823           5 : GroupShape::GroupShape( Drawing& rDrawing ) :
     824             :     ShapeBase( rDrawing ),
     825           5 :     mxChildren( new ShapeContainer( rDrawing ) )
     826             : {
     827           5 : }
     828             : 
     829          10 : GroupShape::~GroupShape()
     830             : {
     831          10 : }
     832             : 
     833           5 : void GroupShape::finalizeFragmentImport()
     834             : {
     835             :     // basic shape processing
     836           5 :     ShapeBase::finalizeFragmentImport();
     837             :     // finalize all child shapes
     838           5 :     mxChildren->finalizeFragmentImport();
     839           5 : }
     840             : 
     841           7 : const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
     842             : {
     843           7 :     return mxChildren->getShapeTypeById( rShapeId, true );
     844             : }
     845             : 
     846           0 : const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
     847             : {
     848           0 :     return mxChildren->getShapeById( rShapeId, true );
     849             : }
     850             : 
     851           5 : Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     852             : {
     853           5 :     Reference< XShape > xGroupShape;
     854             :     // check that this shape contains children and a valid coordinate system
     855           5 :     ShapeParentAnchor aParentAnchor;
     856           5 :     aParentAnchor.maShapeRect = rShapeRect;
     857           5 :     aParentAnchor.maCoordSys = getCoordSystem();
     858           5 :     if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
     859             :     {
     860           5 :         xGroupShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rxShapes, rShapeRect );
     861           5 :         Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
     862           5 :         mxChildren->convertAndInsert( xChildShapes, &aParentAnchor );
     863             :         // no child shape has been created - delete the group shape
     864           5 :         if( !xChildShapes->hasElements() )
     865             :         {
     866           0 :             rxShapes->remove( xGroupShape );
     867           0 :             xGroupShape.clear();
     868           5 :         }
     869             :     }
     870           0 :     catch( Exception& )
     871             :     {
     872             :     }
     873             :     // Make sure group shapes are inline as well, unless there is an explicit different style.
     874           5 :     PropertySet aPropertySet(xGroupShape);
     875           5 :     lcl_SetAnchorType(aPropertySet, maTypeModel);
     876           5 :     return xGroupShape;
     877             : }
     878             : 
     879             : // ============================================================================
     880             : 
     881             : } // namespace vml
     882          51 : } // namespace oox
     883             : 
     884             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10