LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/oox/source/vml - vmlshape.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 385 470 81.9 %
Date: 2013-07-09 Functions: 51 55 92.7 %
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             : #include <boost/optional.hpp>
      22             : 
      23             : #include "oox/vml/vmlshape.hxx"
      24             : 
      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"
      59             : 
      60             : using ::com::sun::star::beans::XPropertySet;
      61             : using ::com::sun::star::uno::Any;
      62             : 
      63             : using namespace ::com::sun::star;
      64             : using namespace ::com::sun::star::text;
      65             : 
      66             : namespace oox {
      67             : namespace vml {
      68             : 
      69             : // ============================================================================
      70             : 
      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;
      76             : 
      77             : using ::oox::core::XmlFilterBase;
      78             : 
      79             : // ============================================================================
      80             : 
      81             : namespace {
      82             : 
      83             : const sal_Int32 VML_SHAPETYPE_PICTUREFRAME  = 75;
      84             : const sal_Int32 VML_SHAPETYPE_HOSTCONTROL   = 201;
      85             : 
      86             : // ----------------------------------------------------------------------------
      87             : 
      88        1075 : awt::Point lclGetAbsPoint( const awt::Point& rRelPoint, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
      89             : {
      90        1075 :     double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
      91        1075 :     double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
      92        1075 :     awt::Point aAbsPoint;
      93        1075 :     aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
      94        1075 :     aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
      95        1075 :     return aAbsPoint;
      96             : }
      97             : 
      98          24 : awt::Rectangle lclGetAbsRect( const awt::Rectangle& rRelRect, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
      99             : {
     100          24 :     double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
     101          24 :     double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
     102          24 :     awt::Rectangle aAbsRect;
     103          24 :     aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
     104          24 :     aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
     105          24 :     aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
     106          24 :     aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
     107          24 :     return aAbsRect;
     108             : }
     109             : 
     110             : } // namespace
     111             : 
     112             : // ============================================================================
     113             : 
     114         101 : ShapeTypeModel::ShapeTypeModel():
     115             :     mbAutoHeight( sal_False ),
     116         101 :     mbVisible( sal_True )
     117             : {
     118         101 : }
     119             : 
     120          29 : void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
     121             : {
     122          29 :     moShapeType.assignIfUsed( rSource.moShapeType );
     123          29 :     moCoordPos.assignIfUsed( rSource.moCoordPos );
     124          29 :     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          29 :     maStrokeModel.assignUsed( rSource.maStrokeModel );
     128          29 :     maFillModel.assignUsed( rSource.maFillModel );
     129          29 :     moGraphicPath.assignIfUsed( rSource.moGraphicPath );
     130          29 :     moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
     131          29 : }
     132             : 
     133             : // ----------------------------------------------------------------------------
     134             : 
     135         101 : ShapeType::ShapeType( Drawing& rDrawing ) :
     136         101 :     mrDrawing( rDrawing )
     137             : {
     138         101 : }
     139             : 
     140         123 : ShapeType::~ShapeType()
     141             : {
     142         123 : }
     143             : 
     144          50 : sal_Int32 ShapeType::getShapeType() const
     145             : {
     146          50 :     return maTypeModel.moShapeType.get( 0 );
     147             : }
     148             : 
     149          58 : OUString ShapeType::getGraphicPath() const
     150             : {
     151          58 :     return maTypeModel.moGraphicPath.get( OUString() );
     152             : }
     153             : 
     154          13 : awt::Rectangle ShapeType::getCoordSystem() const
     155             : {
     156          13 :     Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) );
     157          13 :     Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) );
     158          13 :     if( aCoordSize.first == 0 )
     159           0 :         aCoordSize.first = 1;
     160          13 :     if( aCoordSize.second == 0 )
     161           0 :         aCoordSize.second = 1;
     162          13 :     return awt::Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second );
     163             : }
     164             : 
     165          77 : awt::Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
     166             : {
     167             :     return pParentAnchor ?
     168         125 :         lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
     169         231 :         getAbsRectangle();
     170             : }
     171             : 
     172          51 : awt::Rectangle ShapeType::getAbsRectangle() const
     173             : {
     174          51 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     175             : 
     176          51 :     sal_Int32 nWidth = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true );
     177          51 :     if ( nWidth == 0 )
     178           1 :         nWidth = 1;
     179             : 
     180          51 :     sal_Int32 nHeight = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true );
     181          51 :     if ( nHeight == 0 )
     182           0 :         nHeight = 1;
     183             : 
     184          51 :     sal_Int32 nLeft = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true )
     185          51 :         + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true );
     186          51 :     if (nLeft == 0 && maTypeModel.maPosition == "absolute")
     187          13 :         nLeft = 1;
     188             : 
     189             :     return awt::Rectangle(
     190             :         nLeft,
     191          51 :         ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ),
     192          51 :         nWidth, nHeight );
     193             : }
     194             : 
     195          21 : awt::Rectangle ShapeType::getRelRectangle() const
     196             : {
     197          21 :     sal_Int32 nWidth = maTypeModel.maWidth.toInt32();
     198          21 :     if ( nWidth == 0 )
     199           0 :         nWidth = 1;
     200             : 
     201          21 :     sal_Int32 nHeight = maTypeModel.maHeight.toInt32();
     202          21 :     if ( nHeight == 0 )
     203           0 :         nHeight = 1;
     204             : 
     205             :     return awt::Rectangle(
     206          21 :         maTypeModel.maLeft.toInt32(),
     207          21 :         maTypeModel.maTop.toInt32(),
     208          42 :         nWidth, nHeight );
     209             : }
     210             : 
     211             : // ============================================================================
     212             : 
     213           2 : 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           2 :     mbSecretEdit( false )
     237             : {
     238           2 : }
     239             : 
     240             : // ----------------------------------------------------------------------------
     241             : 
     242          79 : ShapeModel::ShapeModel()
     243             : {
     244          79 : }
     245             : 
     246          79 : ShapeModel::~ShapeModel()
     247             : {
     248          79 : }
     249             : 
     250          36 : TextBox& ShapeModel::createTextBox(ShapeTypeModel& rModel)
     251             : {
     252          36 :     mxTextBox.reset( new TextBox(rModel) );
     253          36 :     return *mxTextBox;
     254             : }
     255             : 
     256           2 : ClientData& ShapeModel::createClientData()
     257             : {
     258           2 :     mxClientData.reset( new ClientData );
     259           2 :     return *mxClientData;
     260             : }
     261             : 
     262             : // ----------------------------------------------------------------------------
     263             : 
     264          79 : ShapeBase::ShapeBase( Drawing& rDrawing ) :
     265          79 :     ShapeType( rDrawing )
     266             : {
     267          79 : }
     268             : 
     269          79 : void ShapeBase::finalizeFragmentImport()
     270             : {
     271          79 :     if( maShapeModel.maType.getLength() > 1 )
     272             :     {
     273          37 :         OUString aType = maShapeModel.maType;
     274          37 :         if (aType[ 0 ] == '#')
     275          35 :             aType = aType.copy(1);
     276          37 :         if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( aType, true ) )
     277          29 :             maTypeModel.assignUsed( pShapeType->getTypeModel() );
     278             :     }
     279          79 : }
     280             : 
     281          57 : OUString ShapeBase::getShapeName() const
     282             : {
     283          57 :     if( !maTypeModel.maShapeName.isEmpty() )
     284          10 :         return maTypeModel.maShapeName;
     285             : 
     286          47 :     OUString aBaseName = mrDrawing.getShapeBaseName( *this );
     287          47 :     if( !aBaseName.isEmpty() )
     288             :     {
     289           1 :         sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() );
     290           1 :         if( nShapeIdx > 0 )
     291           1 :             return OUStringBuffer( aBaseName ).append( sal_Unicode( ' ' ) ).append( nShapeIdx ).makeStringAndClear();
     292             :     }
     293             : 
     294          46 :     return OUString();
     295             : }
     296             : 
     297          15 : const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
     298             : {
     299          15 :     return 0;
     300             : }
     301             : 
     302           0 : const ShapeBase* ShapeBase::getChildById( const OUString& ) const
     303             : {
     304           0 :     return 0;
     305             : }
     306             : 
     307          79 : Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
     308             : {
     309          79 :     Reference< XShape > xShape;
     310          79 :     if( mrDrawing.isShapeSupported( *this ) )
     311             :     {
     312             :         /*  Calculate shape rectangle. Applications may do something special
     313             :             according to some imported shape client data (e.g. Excel cell anchor). */
     314          78 :         awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
     315             : 
     316          78 :         if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
     317             :         {
     318          78 :             xShape = implConvertAndInsert( rxShapes, aShapeRect );
     319          78 :             if( xShape.is() )
     320             :             {
     321             :                 // set imported or generated shape name (not supported by form controls)
     322          78 :                 PropertySet aShapeProp( xShape );
     323          78 :                 if( aShapeProp.hasProperty( PROP_Name ) )
     324          56 :                     aShapeProp.setProperty( PROP_Name, getShapeName() );
     325         156 :                 Reference< XControlShape > xControlShape( xShape, uno::UNO_QUERY );
     326          78 :                 if ( xControlShape.is() && !getTypeModel().mbVisible )
     327             :                 {
     328           0 :                     PropertySet aControlShapeProp( xControlShape->getControl() );
     329           0 :                     aControlShapeProp.setProperty( PROP_EnableVisible, uno::makeAny( sal_False ) );
     330             :                 }
     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          78 :                 bool bGroupChild = pParentAnchor != 0;
     335         156 :                 mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild );
     336             :             }
     337             :         }
     338             :         else
     339             :             SAL_WARN("oox", "not converting shape, as calculated rectangle is empty");
     340             :     }
     341          79 :     return xShape;
     342             : }
     343             : 
     344           1 : void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const
     345             : {
     346           1 :     if( rxShape.is() )
     347             :     {
     348             :         /*  Calculate shape rectangle. Applications may do something special
     349             :             according to some imported shape client data (e.g. Excel cell anchor). */
     350           1 :         awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
     351             : 
     352             :         // convert the shape, if the calculated rectangle is not empty
     353           1 :         if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
     354             :         {
     355           1 :             rxShape->setPosition( awt::Point( aShapeRect.X, aShapeRect.Y ) );
     356           1 :             rxShape->setSize( awt::Size( aShapeRect.Width, aShapeRect.Height ) );
     357           1 :             convertShapeProperties( rxShape );
     358             :         }
     359             :     }
     360           1 : }
     361             : 
     362             : // protected ------------------------------------------------------------------
     363             : 
     364          79 : awt::Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
     365             : {
     366             :     /*  Calculate shape rectangle. Applications may do something special
     367             :         according to some imported shape client data (e.g. Excel cell anchor). */
     368          79 :     awt::Rectangle aShapeRect;
     369          79 :     const ClientData* pClientData = getClientData();
     370          79 :     if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) )
     371          77 :         aShapeRect = getRectangle( pParentAnchor );
     372          79 :     return aShapeRect;
     373             : }
     374             : 
     375          64 : void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
     376             : {
     377          64 :     ::oox::drawingml::ShapePropertyMap aPropMap( mrDrawing.getFilter().getModelObjectHelper() );
     378          64 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     379          64 :     maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper );
     380          64 :     maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper );
     381             : 
     382         128 :     uno::Reference<lang::XServiceInfo> xSInfo(rxShape, uno::UNO_QUERY_THROW);
     383          64 :     if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
     384             :     {
     385             :         // Any other service supporting the ShadowFormat property?
     386          21 :         maTypeModel.maShadowModel.pushToPropMap(aPropMap, rGraphicHelper);
     387             :         // TextFrames have BackColor, not FillColor
     388          21 :         if (aPropMap.hasProperty(PROP_FillColor))
     389             :         {
     390          12 :             aPropMap.setProperty(PROP_BackColor, aPropMap[PROP_FillColor]);
     391          12 :             aPropMap.erase(PROP_FillColor);
     392             :         }
     393             :         // And no LineColor property; individual borders can have colors and widths
     394          21 :         boost::optional<sal_Int32> oLineWidth;
     395          21 :         if (maTypeModel.maStrokeModel.moWeight.has())
     396          12 :             oLineWidth.reset(ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maTypeModel.maStrokeModel.moWeight.get(), 0, false, false));
     397          21 :         if (aPropMap.hasProperty(PROP_LineColor))
     398             :         {
     399          17 :             uno::Reference<beans::XPropertySet> xPropertySet(rxShape, uno::UNO_QUERY);
     400             :             static sal_Int32 aBorders[] = {
     401             :                 PROP_TopBorder, PROP_LeftBorder, PROP_BottomBorder, PROP_RightBorder
     402             :             };
     403          85 :             for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
     404             :             {
     405          68 :                 table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(PropertyMap::getPropertyName(aBorders[i])).get<table::BorderLine2>();
     406          68 :                 aBorderLine.Color = aPropMap[PROP_LineColor].get<sal_Int32>();
     407          68 :                 if (oLineWidth)
     408          48 :                     aBorderLine.LineWidth = *oLineWidth;
     409          68 :                 aPropMap.setProperty(aBorders[i], uno::makeAny(aBorderLine));
     410             :             }
     411          17 :             aPropMap.erase(PROP_LineColor);
     412          21 :         }
     413             :     }
     414          43 :     else if (xSInfo->supportsService("com.sun.star.drawing.CustomShape"))
     415          26 :         maTypeModel.maTextpathModel.pushToPropMap(aPropMap, rxShape);
     416             : 
     417         128 :     PropertySet( rxShape ).setProperties( aPropMap );
     418          64 : }
     419             : 
     420             : // ============================================================================
     421             : 
     422          68 : SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :
     423             :     ShapeBase( rDrawing ),
     424          68 :     maService( rService )
     425             : {
     426          68 : }
     427             : 
     428          77 : void lcl_setSurround(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
     429             : {
     430          77 :     sal_Int32 nSurround = com::sun::star::text::WrapTextMode_THROUGHT;
     431         151 :     if ( rTypeModel.moWrapType.get() == "square" || rTypeModel.moWrapType .get()== "tight" ||
     432          74 :          rTypeModel.moWrapType.get() == "through" )
     433             :     {
     434           3 :         nSurround = com::sun::star::text::WrapTextMode_PARALLEL;
     435           3 :         if ( rTypeModel.moWrapSide.get() == "left" )
     436           0 :             nSurround = com::sun::star::text::WrapTextMode_LEFT;
     437           3 :         else if ( rTypeModel.moWrapSide.get() == "right" )
     438           0 :             nSurround = com::sun::star::text::WrapTextMode_RIGHT;
     439             :     }
     440          74 :     else if ( rTypeModel.moWrapType.get() == "topAndBottom" )
     441           0 :         nSurround = com::sun::star::text::WrapTextMode_NONE;
     442             : 
     443          77 :     rPropSet.setProperty(PROP_Surround, nSurround);
     444          77 : }
     445             : 
     446          77 : void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
     447             : {
     448          77 :     if ( rTypeModel.maPositionHorizontal == "center" )
     449           9 :         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));
     450             : 
     451          77 :     if ( rTypeModel.maPositionHorizontalRelative == "page" )
     452           4 :         rPropSet.setAnyProperty(PROP_HoriOrientRelation, makeAny(text::RelOrientation::PAGE_FRAME));
     453             : 
     454          77 :     if ( rTypeModel.maPositionVertical == "center" )
     455           5 :         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::CENTER));
     456             : 
     457          77 :     if ( rTypeModel.maPosition == "absolute" )
     458             :     {
     459             :         // Word supports as-character (inline) and at-character only, absolute can't be inline.
     460          61 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
     461             : 
     462          61 :         if ( rTypeModel.maPositionVerticalRelative == "page" )
     463             :         {
     464           3 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
     465             :         }
     466          58 :         else if ( rTypeModel.maPositionVerticalRelative == "margin" )
     467             :         {
     468           9 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_PRINT_AREA);
     469             :         }
     470             :         else
     471             :         {
     472             :             // Vertical placement relative to margin, because parent style must not modify vertical position
     473          49 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
     474             :         }
     475             :     }
     476          16 :     else if( rTypeModel.maPosition == "relative" )
     477             :     {   // I'm not very sure this is correct either.
     478           0 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PARAGRAPH);
     479             :     }
     480             :     else // static (is the default) means anchored inline
     481             :     {
     482          16 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AS_CHARACTER);
     483             :     }
     484          77 :     lcl_setSurround( rPropSet, rTypeModel );
     485          77 : }
     486             : 
     487          50 : Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     488             : {
     489          50 :     awt::Rectangle aShapeRect(rShapeRect);
     490          50 :     boost::optional<sal_Int32> oRotation;
     491          50 :     if (!maTypeModel.maRotation.isEmpty())
     492           3 :         oRotation.reset(maTypeModel.maRotation.toInt32());
     493          50 :     if (!maTypeModel.maFlip.isEmpty())
     494             :     {
     495           3 :         if (maTypeModel.maFlip.equalsAscii("x"))
     496             :         {
     497           2 :             aShapeRect.X += aShapeRect.Width;
     498           2 :             aShapeRect.Width *= -1;
     499           2 :             if (oRotation)
     500           1 :                 oRotation.reset(360 - *oRotation);
     501             :         }
     502           1 :         else if (maTypeModel.maFlip.equalsAscii("y"))
     503             :         {
     504           0 :             aShapeRect.Y += aShapeRect.Height;
     505           0 :             aShapeRect.Height *= -1;
     506             :         }
     507             :     }
     508             : 
     509          50 :     Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, aShapeRect );
     510          50 :     convertShapeProperties( xShape );
     511             : 
     512          50 :     if ( maService.equalsAscii( "com.sun.star.text.TextFrame" ) )
     513             :     {
     514          21 :         PropertySet( xShape ).setAnyProperty( PROP_FrameIsAutomaticHeight, makeAny( maTypeModel.mbAutoHeight ) );
     515          21 :         PropertySet( xShape ).setAnyProperty( PROP_SizeType, makeAny( maTypeModel.mbAutoHeight ? SizeType::MIN : SizeType::FIX ) );
     516          21 :         if( getTextBox()->borderDistanceSet )
     517             :         {
     518          21 :             PropertySet( xShape ).setAnyProperty( PROP_LeftBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceLeft )));
     519          21 :             PropertySet( xShape ).setAnyProperty( PROP_TopBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceTop )));
     520          21 :             PropertySet( xShape ).setAnyProperty( PROP_RightBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceRight )));
     521          21 :             PropertySet( xShape ).setAnyProperty( PROP_BottomBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceBottom )));
     522             :         }
     523             :     }
     524             :     else
     525             :     {
     526             :         // FIXME Setting the relative width/heigh only for everything but text frames as
     527             :         // TextFrames already have relative widht/heigh feature... but currently not working
     528             :         // in the way we need.
     529             : 
     530             :         // Set the relative width / height if any
     531          29 :         if ( !maTypeModel.maWidthPercent.isEmpty( ) )
     532             :         {
     533             :             // Only page-relative width is supported ATM
     534           3 :             if ( maTypeModel.maWidthRelative.isEmpty() || maTypeModel.maWidthRelative == "page" )
     535             :             {
     536           1 :                 sal_Int16 nWidth = maTypeModel.maWidthPercent.toInt32() / 10;
     537             :                 // Only apply if nWidth != 0
     538           1 :                 if ( nWidth )
     539           1 :                     PropertySet( xShape ).setAnyProperty(PROP_RelativeWidth, makeAny( nWidth ) );
     540             :             }
     541             :         }
     542          29 :         if ( !maTypeModel.maHeightPercent.isEmpty( ) )
     543             :         {
     544             :             // Only page-relative height is supported ATM
     545           1 :             if ( maTypeModel.maHeightRelative.isEmpty() || maTypeModel.maHeightRelative == "page" )
     546             :             {
     547           1 :                 sal_Int16 nHeight = maTypeModel.maHeightPercent.toInt32() / 10;
     548             :                 // Only apply if nHeight != 0
     549           1 :                 if ( nHeight )
     550           1 :                     PropertySet( xShape ).setAnyProperty(PROP_RelativeHeight, makeAny( nHeight ) );
     551             :             }
     552             :         }
     553             : 
     554             :         // drawinglayer default is center, MSO default is top.
     555          29 :         drawing::TextVerticalAdjust eTextVerticalAdjust = drawing::TextVerticalAdjust_TOP;
     556          29 :         if (maTypeModel.maVTextAnchor == "middle")
     557           0 :             eTextVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
     558          29 :         else if (maTypeModel.maVTextAnchor == "bottom")
     559           1 :             eTextVerticalAdjust = drawing::TextVerticalAdjust_BOTTOM;
     560          29 :         PropertySet(xShape).setAnyProperty(PROP_TextVerticalAdjust, makeAny(eTextVerticalAdjust));
     561             : 
     562          29 :         if (getTextBox())
     563          11 :             getTextBox()->convert(xShape);
     564             :     }
     565             : 
     566             :     // Import Legacy Fragments (if any)
     567          50 :     if( xShape.is() && !maShapeModel.maLegacyDiagramPath.isEmpty() )
     568             :     {
     569           0 :         Reference< XInputStream > xInStrm( mrDrawing.getFilter().openInputStream( maShapeModel.maLegacyDiagramPath ), UNO_SET_THROW );
     570           0 :         if( xInStrm.is() )
     571           0 :             PropertySet( xShape ).setProperty( PROP_LegacyFragment, xInStrm );
     572             :     }
     573             : 
     574         100 :     PropertySet aPropertySet(xShape);
     575          50 :     if (xShape.is() && oRotation)
     576             :     {
     577             :         // See DffPropertyReader::Fix16ToAngle(): in VML, positive rotation angles are clockwise, we have them as counter-clockwise.
     578             :         // Additionally, VML type is 0..360, our is 0.36000.
     579           3 :         aPropertySet.setAnyProperty(PROP_RotateAngle, makeAny(sal_Int32(NormAngle360((*oRotation) * -100))));
     580             :         // If rotation is used, simple setPosition() is not enough.
     581           3 :         aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) );
     582           3 :         aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) );
     583             :     }
     584             : 
     585          50 :     lcl_SetAnchorType(aPropertySet, maTypeModel);
     586             : 
     587         100 :     return xShape;
     588             : }
     589             : 
     590          16 : Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString& rGraphicPath ) const
     591             : {
     592          16 :     Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GraphicObjectShape", rxShapes, rShapeRect );
     593          16 :     if( xShape.is() )
     594             :     {
     595          16 :         XmlFilterBase& rFilter = mrDrawing.getFilter();
     596          16 :         OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( rGraphicPath );
     597          32 :         PropertySet aPropSet( xShape );
     598          16 :         if( !aGraphicUrl.isEmpty() )
     599             :         {
     600          16 :             aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
     601             :         }
     602          32 :         uno::Reference< lang::XServiceInfo > xServiceInfo(rxShapes, uno::UNO_QUERY);
     603             :         // If the shape has an absolute position, set the properties accordingly, unless we're inside a group shape.
     604          16 :         if ( maTypeModel.maPosition == "absolute" && !xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
     605             :         {
     606           4 :             aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
     607           4 :             aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
     608           4 :             aPropSet.setProperty(PROP_Opaque, sal_False);
     609             :         }
     610             : 
     611          32 :         lcl_SetAnchorType(aPropSet, maTypeModel);
     612             :     }
     613          16 :     return xShape;
     614             : }
     615             : 
     616             : // ============================================================================
     617             : 
     618          21 : RectangleShape::RectangleShape( Drawing& rDrawing ) :
     619          21 :     SimpleShape( rDrawing, "com.sun.star.drawing.RectangleShape" )
     620             : {
     621          21 : }
     622             : 
     623          21 : Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const awt::Rectangle& rShapeRect) const
     624             : {
     625          21 :     OUString aGraphicPath = getGraphicPath();
     626             : 
     627             :     // try to create a picture object
     628          21 :     if(!aGraphicPath.isEmpty())
     629           1 :         return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
     630             : 
     631             :     // default: try to create a rectangle shape
     632          40 :     Reference<XShape> xShape = SimpleShape::implConvertAndInsert(rxShapes, rShapeRect);
     633          40 :     OUString sArcsize = maTypeModel.maArcsize;
     634          20 :     if ( !sArcsize.isEmpty( ) )
     635             :     {
     636           1 :         sal_Unicode cLastChar = sArcsize[sArcsize.getLength() - 1];
     637           1 :         sal_Int32 nValue = sArcsize.copy( 0, sArcsize.getLength() - 1 ).toInt32( );
     638             :         // Get the smallest half-side
     639           1 :         double size = std::min( rShapeRect.Height, rShapeRect.Width ) / 2.0;
     640           1 :         sal_Int32 nRadius = 0;
     641           1 :         if ( cLastChar == 'f' )
     642           1 :             nRadius = size * nValue / 65536;
     643           0 :         else if ( cLastChar == '%' )
     644           0 :             nRadius = size * nValue / 100;
     645           1 :         PropertySet( xShape ).setAnyProperty( PROP_CornerRadius, makeAny( nRadius ) );
     646             :     }
     647          41 :     return xShape;
     648             : }
     649             : 
     650             : // ============================================================================
     651             : 
     652           2 : EllipseShape::EllipseShape( Drawing& rDrawing ) :
     653           2 :     SimpleShape( rDrawing, "com.sun.star.drawing.EllipseShape" )
     654             : {
     655           2 : }
     656             : 
     657             : // ============================================================================
     658             : 
     659           0 : PolyLineShape::PolyLineShape( Drawing& rDrawing ) :
     660           0 :     SimpleShape( rDrawing, "com.sun.star.drawing.PolyLineShape" )
     661             : {
     662           0 : }
     663             : 
     664           0 : Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     665             : {
     666           0 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     667             :     // polygon path
     668           0 :     awt::Rectangle aCoordSys = getCoordSystem();
     669           0 :     if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
     670             :     {
     671           0 :         ::std::vector< awt::Point > aAbsPoints;
     672           0 :         for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
     673           0 :             aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
     674           0 :         PointSequenceSequence aPointSeq( 1 );
     675           0 :         aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
     676           0 :         PropertySet aPropSet( xShape );
     677           0 :         aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
     678             :     }
     679           0 :     return xShape;
     680             : }
     681             : 
     682           5 : LineShape::LineShape(Drawing& rDrawing)
     683           5 :     : SimpleShape(rDrawing, "com.sun.star.drawing.LineShape")
     684             : {
     685           5 : }
     686             : 
     687           2 : awt::Rectangle LineShape::getAbsRectangle() const
     688             : {
     689           2 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     690           2 :     awt::Rectangle aShapeRect;
     691           2 :     sal_Int32 nIndex = 0;
     692             : 
     693           2 :     aShapeRect.X = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, true, true);
     694           2 :     aShapeRect.Y = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, false, true);
     695           2 :     nIndex = 0;
     696           2 :     aShapeRect.Width = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, true, true) - aShapeRect.X;
     697           2 :     aShapeRect.Height = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, false, true) - aShapeRect.Y;
     698           2 :     return aShapeRect;
     699             : }
     700             : 
     701           3 : awt::Rectangle LineShape::getRelRectangle() const
     702             : {
     703           3 :     awt::Rectangle aShapeRect;
     704           3 :     sal_Int32 nIndex = 0;
     705             : 
     706           3 :     aShapeRect.X = maShapeModel.maFrom.getToken(0, ',', nIndex).toInt32();
     707           3 :     aShapeRect.Y = maShapeModel.maFrom.getToken(0, ',', nIndex).toInt32();
     708           3 :     nIndex = 0;
     709           3 :     aShapeRect.Width = maShapeModel.maTo.getToken(0, ',', nIndex).toInt32() - aShapeRect.X;
     710           3 :     aShapeRect.Height = maShapeModel.maTo.getToken(0, ',', nIndex).toInt32() - aShapeRect.Y;
     711           3 :     return aShapeRect;
     712             : }
     713             : 
     714             : // ============================================================================
     715             : 
     716           2 : BezierShape::BezierShape(Drawing& rDrawing)
     717           2 :     : SimpleShape(rDrawing, "com.sun.star.drawing.OpenBezierShape")
     718             : {
     719           2 : }
     720             : 
     721           2 : Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     722             : {
     723             :     // If we have an 'x' in the last part of the path it means it is closed...
     724           2 :     sal_Int32 nPos = maShapeModel.maVmlPath.lastIndexOf(',');
     725           2 :     if ( nPos != -1 && maShapeModel.maVmlPath.copy(nPos).indexOf('x') != -1 )
     726             :     {
     727           1 :         const_cast<BezierShape*>( this )->setService( "com.sun.star.drawing.ClosedBezierShape" );
     728             :     }
     729             : 
     730           2 :     awt::Rectangle aCoordSys = getCoordSystem();
     731           2 :     PolyPolygonBezierCoords aBezierCoords;
     732             : 
     733           2 :     if( (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
     734             :     {
     735           2 :         const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     736             : 
     737             :         // Bezier paths may consist of one or more sub-paths
     738             :         typedef ::std::vector< ::std::vector< awt::Point > > SubPathList;
     739             :         typedef ::std::vector< ::std::vector< PolygonFlags > > FlagsList;
     740           2 :         SubPathList aCoordLists;
     741           4 :         FlagsList aFlagLists;
     742           2 :         sal_Int32 nIndex = 0;
     743             : 
     744             :         // Curve defined by to, from, control1 and control2 attributes
     745           2 :         if ( maShapeModel.maVmlPath.isEmpty() )
     746             :         {
     747           0 :             aCoordLists.push_back( ::std::vector< awt::Point >() );
     748           0 :             aFlagLists.push_back( ::std::vector< PolygonFlags >() );
     749             : 
     750             :             // Start point
     751           0 :             aCoordLists[ 0 ].push_back(
     752           0 :                 awt::Point(ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, true, true ),
     753           0 :                   ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     754             :             // Control point 1
     755           0 :             aCoordLists[ 0 ].push_back(
     756           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, true, true ),
     757           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     758             :             // Control point 2
     759           0 :             aCoordLists[ 0 ].push_back(
     760           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, true, true ),
     761           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     762             :             // End point
     763           0 :             aCoordLists[ 0 ].push_back(
     764           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, true, true ),
     765           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     766             : 
     767             :             // First and last points are normals, points 2 and 4 are controls
     768           0 :             aFlagLists[ 0 ].resize( aCoordLists[ 0 ].size(), PolygonFlags_CONTROL );
     769           0 :             aFlagLists[ 0 ][ 0 ] = PolygonFlags_NORMAL;
     770           0 :             aFlagLists[ 0 ].back() = PolygonFlags_NORMAL;
     771             :         }
     772             :         // Curve defined by path attribute
     773             :         else
     774             :         {
     775             :             // Parse VML path string and convert to absolute coordinates
     776           2 :             ConversionHelper::decodeVmlPath( aCoordLists, aFlagLists, maShapeModel.maVmlPath );
     777             : 
     778         132 :             for ( SubPathList::iterator aListIt = aCoordLists.begin(); aListIt != aCoordLists.end(); ++aListIt )
     779        1205 :                 for ( ::std::vector< awt::Point >::iterator aPointIt = (*aListIt).begin(); aPointIt != (*aListIt).end(); ++aPointIt)
     780             :                 {
     781        1075 :                     (*aPointIt) = lclGetAbsPoint( (*aPointIt), rShapeRect, aCoordSys );
     782             :                 }
     783             :         }
     784             : 
     785           2 :         aBezierCoords.Coordinates.realloc( aCoordLists.size() );
     786         132 :         for ( unsigned int i = 0; i < aCoordLists.size(); i++ )
     787         130 :             aBezierCoords.Coordinates[i] = ContainerHelper::vectorToSequence( aCoordLists[i] );
     788             : 
     789           2 :         aBezierCoords.Flags.realloc( aFlagLists.size() );
     790         132 :         for ( unsigned int i = 0; i < aFlagLists.size(); i++ )
     791         130 :             aBezierCoords.Flags[i] = ContainerHelper::vectorToSequence( aFlagLists[i] );
     792             : 
     793           6 :         if( !aCoordLists.front().empty() && !aCoordLists.back().empty()
     794           2 :             && aCoordLists.front().front().X == aCoordLists.back().back().X
     795           2 :             && aCoordLists.front().front().Y == aCoordLists.back().back().Y )
     796             :         { // HACK: If the shape is in fact closed, which can be found out only when the path is known,
     797             :           // force to closed bezier shape (otherwise e.g. fill won't work).
     798           0 :             const_cast< BezierShape* >( this )->setService( "com.sun.star.drawing.ClosedBezierShape" );
     799           2 :         }
     800             :     }
     801             : 
     802           2 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     803             : 
     804           2 :     if( aBezierCoords.Coordinates.hasElements())
     805             :     {
     806           2 :         PropertySet aPropSet( xShape );
     807           2 :         aPropSet.setProperty( PROP_PolyPolygonBezier, aBezierCoords );
     808             :     }
     809             : 
     810             :     // Hacky way of ensuring the shape is correctly sized/positioned
     811           2 :     xShape->setSize( awt::Size( rShapeRect.Width, rShapeRect.Height ) );
     812           2 :     xShape->setPosition( awt::Point( rShapeRect.X, rShapeRect.Y ) );
     813           2 :     return xShape;
     814             : }
     815             : 
     816             : // ============================================================================
     817             : 
     818          38 : CustomShape::CustomShape( Drawing& rDrawing ) :
     819          38 :     SimpleShape( rDrawing, "com.sun.star.drawing.CustomShape" )
     820             : {
     821          38 : }
     822             : 
     823          21 : Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     824             : {
     825             :     // try to create a custom shape
     826          21 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     827          21 :     if( xShape.is() ) try
     828             :     {
     829             :         // create the custom shape geometry
     830          21 :         Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
     831          13 :         xDefaulter->createCustomShapeDefaults( OUString::valueOf( getShapeType() ) );
     832             :         // convert common properties
     833          13 :         convertShapeProperties( xShape );
     834             :     }
     835           8 :     catch( Exception& )
     836             :     {
     837             :     }
     838          21 :     return xShape;
     839             : }
     840             : 
     841             : // ============================================================================
     842             : 
     843          38 : ComplexShape::ComplexShape( Drawing& rDrawing ) :
     844          38 :     CustomShape( rDrawing )
     845             : {
     846          38 : }
     847             : 
     848          37 : Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     849             : {
     850          37 :     XmlFilterBase& rFilter = mrDrawing.getFilter();
     851          37 :     sal_Int32 nShapeType = getShapeType();
     852          37 :     OUString aGraphicPath = getGraphicPath();
     853             : 
     854             :     // try to find registered OLE object info
     855          37 :     if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
     856             :     {
     857             :         OSL_ENSURE( nShapeType == VML_SHAPETYPE_PICTUREFRAME, "ComplexShape::implConvertAndInsert - unexpected shape type" );
     858             : 
     859             :         // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
     860           0 :         if( pOleObjectInfo->mbDmlShape )
     861           0 :             return Reference< XShape >();
     862             : 
     863           0 :         PropertyMap aOleProps;
     864           0 :         awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
     865           0 :         if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
     866             :         {
     867           0 :             Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.OLE2Shape", rxShapes, rShapeRect );
     868           0 :             if( xShape.is() )
     869             :             {
     870             :                 // set the replacement graphic
     871           0 :                 if( !aGraphicPath.isEmpty() )
     872             :                 {
     873           0 :                     Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
     874           0 :                     if( xGraphic.is() )
     875           0 :                         aOleProps[ PROP_Graphic ] <<= xGraphic;
     876             :                 }
     877             : 
     878           0 :                 PropertySet aPropSet( xShape );
     879           0 :                 aPropSet.setProperties( aOleProps );
     880             : 
     881           0 :                 return xShape;
     882           0 :             }
     883           0 :         }
     884             :     }
     885             : 
     886             :     // try to find registered form control info
     887          37 :     const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
     888          37 :     if( pControlInfo && !pControlInfo->maFragmentPath.isEmpty() )
     889             :     {
     890             :         OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
     891           0 :         OUString aShapeName = getShapeName();
     892           0 :         if( !aShapeName.isEmpty() )
     893             :         {
     894             :             OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
     895             :             // load the control properties from fragment
     896           0 :             ::oox::ole::EmbeddedControl aControl( aShapeName );
     897           0 :             if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
     898             :             {
     899             :                 // create and return the control shape (including control model)
     900           0 :                 sal_Int32 nCtrlIndex = -1;
     901           0 :                 Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
     902             :                 // on error, proceed and try to create picture from replacement image
     903           0 :                 if( xShape.is() )
     904           0 :                     return xShape;
     905           0 :             }
     906           0 :         }
     907             :     }
     908             : 
     909             :     // host application wants to create the shape (do not try failed OLE controls again)
     910          37 :     if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo )
     911             :     {
     912             :         OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" );
     913           1 :         Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect );
     914           1 :         if( xShape.is() )
     915           1 :             return xShape;
     916             :     }
     917             : 
     918             :     // try to create a picture object
     919          36 :     if( !aGraphicPath.isEmpty() )
     920          15 :         return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
     921             : 
     922             :     // default: try to create a custom shape
     923          21 :     return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
     924             : }
     925             : 
     926             : // ============================================================================
     927             : 
     928          11 : GroupShape::GroupShape( Drawing& rDrawing ) :
     929             :     ShapeBase( rDrawing ),
     930          11 :     mxChildren( new ShapeContainer( rDrawing ) )
     931             : {
     932          11 : }
     933             : 
     934          22 : GroupShape::~GroupShape()
     935             : {
     936          22 : }
     937             : 
     938          11 : void GroupShape::finalizeFragmentImport()
     939             : {
     940             :     // basic shape processing
     941          11 :     ShapeBase::finalizeFragmentImport();
     942             :     // finalize all child shapes
     943          11 :     mxChildren->finalizeFragmentImport();
     944          11 : }
     945             : 
     946          19 : const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
     947             : {
     948          19 :     return mxChildren->getShapeTypeById( rShapeId, true );
     949             : }
     950             : 
     951           0 : const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
     952             : {
     953           0 :     return mxChildren->getShapeById( rShapeId, true );
     954             : }
     955             : 
     956          11 : Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     957             : {
     958          11 :     Reference< XShape > xGroupShape;
     959             :     // check that this shape contains children and a valid coordinate system
     960          11 :     ShapeParentAnchor aParentAnchor;
     961          11 :     aParentAnchor.maShapeRect = rShapeRect;
     962          11 :     aParentAnchor.maCoordSys = getCoordSystem();
     963          11 :     if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
     964             :     {
     965          11 :         xGroupShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GroupShape", rxShapes, rShapeRect );
     966          11 :         Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
     967          11 :         mxChildren->convertAndInsert( xChildShapes, &aParentAnchor );
     968          11 :         if( !xChildShapes->hasElements() )
     969             :         {
     970             :             SAL_WARN("oox", "no child shape has been created - deleting the group shape");
     971           0 :             rxShapes->remove( xGroupShape );
     972           0 :             xGroupShape.clear();
     973          11 :         }
     974             :     }
     975           0 :     catch( Exception& )
     976             :     {
     977             :     }
     978             :     // Make sure group shapes are inline as well, unless there is an explicit different style.
     979          22 :     PropertySet aPropertySet(xGroupShape);
     980          11 :     lcl_SetAnchorType(aPropertySet, maTypeModel);
     981          22 :     return xGroupShape;
     982             : }
     983             : 
     984             : // ============================================================================
     985             : 
     986             : } // namespace vml
     987         141 : } // namespace oox
     988             : 
     989             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10