LCOV - code coverage report
Current view: top level - oox/source/export - shapes.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 544 715 76.1 %
Date: 2015-06-13 12:38:46 Functions: 33 40 82.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 <sal/config.h>
      21             : 
      22             : #include <config_global.h>
      23             : #include <unotools/mediadescriptor.hxx>
      24             : #include <filter/msfilter/util.hxx>
      25             : #include "oox/core/xmlfilterbase.hxx"
      26             : #include "oox/export/shapes.hxx"
      27             : #include "oox/export/utils.hxx"
      28             : #include <oox/token/tokens.hxx>
      29             : 
      30             : #include <cstdio>
      31             : #include <initializer_list>
      32             : 
      33             : #include <com/sun/star/awt/CharSet.hpp>
      34             : #include <com/sun/star/awt/FontDescriptor.hpp>
      35             : #include <com/sun/star/awt/FontSlant.hpp>
      36             : #include <com/sun/star/awt/FontWeight.hpp>
      37             : #include <com/sun/star/awt/FontUnderline.hpp>
      38             : #include <com/sun/star/awt/Gradient.hpp>
      39             : #include <com/sun/star/beans/XPropertySet.hpp>
      40             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      41             : #include <com/sun/star/beans/XPropertyState.hpp>
      42             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      43             : #include <com/sun/star/document/XExporter.hpp>
      44             : #include <com/sun/star/drawing/FillStyle.hpp>
      45             : #include <com/sun/star/drawing/BitmapMode.hpp>
      46             : #include <com/sun/star/drawing/ConnectorType.hpp>
      47             : #include <com/sun/star/drawing/LineDash.hpp>
      48             : #include <com/sun/star/drawing/LineJoint.hpp>
      49             : #include <com/sun/star/drawing/LineStyle.hpp>
      50             : #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
      51             : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
      52             : #include <com/sun/star/graphic/XGraphic.hpp>
      53             : #include <com/sun/star/i18n/ScriptType.hpp>
      54             : #include <com/sun/star/io/XOutputStream.hpp>
      55             : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
      56             : #include <com/sun/star/style/ParagraphAdjust.hpp>
      57             : #include <com/sun/star/text/XSimpleText.hpp>
      58             : #include <com/sun/star/text/XText.hpp>
      59             : #include <com/sun/star/text/XTextContent.hpp>
      60             : #include <com/sun/star/text/XTextDocument.hpp>
      61             : #include <com/sun/star/text/XTextField.hpp>
      62             : #include <com/sun/star/text/XTextRange.hpp>
      63             : #include <com/sun/star/table/XTable.hpp>
      64             : #include <com/sun/star/table/XColumnRowRange.hpp>
      65             : #include <com/sun/star/table/XCellRange.hpp>
      66             : #include <com/sun/star/table/XMergeableCell.hpp>
      67             : #include <com/sun/star/chart2/XChartDocument.hpp>
      68             : #include <com/sun/star/frame/XModel.hpp>
      69             : #include <com/sun/star/table/BorderLine2.hpp>
      70             : #include <tools/stream.hxx>
      71             : #include <vcl/cvtgrf.hxx>
      72             : #include <unotools/fontcvt.hxx>
      73             : #include <vcl/graph.hxx>
      74             : #include <vcl/outdev.hxx>
      75             : #include <svtools/grfmgr.hxx>
      76             : #include <rtl/strbuf.hxx>
      77             : #include <sfx2/app.hxx>
      78             : #include <svl/languageoptions.hxx>
      79             : #include <filter/msfilter/escherex.hxx>
      80             : #include <svx/svdoashp.hxx>
      81             : #include <svx/svdoole2.hxx>
      82             : #include <editeng/svxenum.hxx>
      83             : #include <svx/unoapi.hxx>
      84             : #include <oox/export/chartexport.hxx>
      85             : 
      86             : using namespace ::css;
      87             : using namespace ::css::beans;
      88             : using namespace ::css::uno;
      89             : using namespace ::css::drawing;
      90             : using namespace ::css::i18n;
      91             : using namespace ::css::table;
      92             : using namespace ::css::container;
      93             : using namespace ::css::document;
      94             : using namespace ::css::text;
      95             : 
      96             : using ::css::graphic::XGraphic;
      97             : using ::css::io::XOutputStream;
      98             : using ::css::lang::XComponent;
      99             : using ::css::chart2::XChartDocument;
     100             : using ::css::frame::XModel;
     101             : using ::css::sheet::XSpreadsheetDocument;
     102             : 
     103             : using ::oox::core::XmlFilterBase;
     104             : using ::sax_fastparser::FSHelperPtr;
     105             : 
     106             : #define IDS(x) OString(OStringLiteral(#x " ") + OString::number( mnShapeIdMax++ )).getStr()
     107             : 
     108             : namespace oox { namespace drawingml {
     109             : 
     110        1510 : URLTransformer::~URLTransformer()
     111             : {
     112        1510 : }
     113             : 
     114           0 : OUString URLTransformer::getTransformedString(const OUString& rString) const
     115             : {
     116           0 :     return rString;
     117             : }
     118             : 
     119           0 : bool URLTransformer::isExternalURL(const OUString& /*rURL*/) const
     120             : {
     121           0 :     return true;
     122             : }
     123             : 
     124             : #define GETA(propName) \
     125             :     GetProperty( rXPropSet, OUString(#propName))
     126             : 
     127             : #define GETAD(propName) \
     128             :     ( GetPropertyAndState( rXPropSet, rXPropState, OUString(#propName), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
     129             : 
     130             : #define GET(variable, propName) \
     131             :     if ( GETA(propName) ) \
     132             :         mAny >>= variable;
     133             : 
     134             : // not thread safe
     135             : int ShapeExport::mnEmbeddeDocumentCounter = 1;
     136             : 
     137         744 : ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ShapeHashMap* pShapeMap, XmlFilterBase* pFB, DocumentType eDocumentType, DMLTextExport* pTextExport )
     138             :     : DrawingML( pFS, pFB, eDocumentType, pTextExport )
     139             :     , mnShapeIdMax( 1 )
     140             :     , mnPictureIdMax( 1 )
     141             :     , mnXmlNamespace( nXmlNamespace )
     142             :     , maFraction( 1, 576 )
     143             :     , maMapModeSrc( MAP_100TH_MM )
     144             :     , maMapModeDest( MAP_INCH, Point(), maFraction, maFraction )
     145         744 :     , mpShapeMap( pShapeMap ? pShapeMap : &maShapeMap )
     146             : {
     147         744 :     mpURLTransformer.reset(new URLTransformer);
     148         744 : }
     149             : 
     150          22 : void ShapeExport::SetURLTranslator(std::shared_ptr<URLTransformer> pTransformer)
     151             : {
     152          22 :     mpURLTransformer = pTransformer;
     153          22 : }
     154             : 
     155           0 : awt::Size ShapeExport::MapSize( const awt::Size& rSize ) const
     156             : {
     157           0 :     Size aRetSize( OutputDevice::LogicToLogic( Size( rSize.Width, rSize.Height ), maMapModeSrc, maMapModeDest ) );
     158             : 
     159           0 :     if ( !aRetSize.Width() )
     160           0 :         aRetSize.Width()++;
     161           0 :     if ( !aRetSize.Height() )
     162           0 :         aRetSize.Height()++;
     163           0 :     return awt::Size( aRetSize.Width(), aRetSize.Height() );
     164             : }
     165             : 
     166        2538 : bool ShapeExport::NonEmptyText( Reference< XInterface > xIface )
     167             : {
     168        2538 :     Reference< XPropertySet > xPropSet( xIface, UNO_QUERY );
     169             : 
     170        2538 :     if( xPropSet.is() )
     171             :     {
     172        2538 :         Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
     173        2538 :         if ( xPropSetInfo.is() )
     174             :         {
     175        2538 :             if ( xPropSetInfo->hasPropertyByName( "IsEmptyPresentationObject" ) )
     176             :             {
     177        2002 :                 bool bIsEmptyPresObj = false;
     178        2002 :                 if ( xPropSet->getPropertyValue( "IsEmptyPresentationObject" ) >>= bIsEmptyPresObj )
     179             :                 {
     180             :                     SAL_INFO("oox.shape", "empty presentation object " << bIsEmptyPresObj << " , props:");
     181        2002 :                     if( bIsEmptyPresObj )
     182        1763 :                        return true;
     183             :                 }
     184             :             }
     185             : 
     186         775 :             if ( xPropSetInfo->hasPropertyByName( "IsPresentationObject" ) )
     187             :             {
     188         239 :                 bool bIsPresObj = false;
     189         239 :                 if ( xPropSet->getPropertyValue( "IsPresentationObject" ) >>= bIsPresObj )
     190             :                 {
     191             :                     SAL_INFO("oox.shape", "presentation object " << bIsPresObj << ", props:");
     192         239 :                     if( bIsPresObj )
     193         208 :                        return true;
     194             :                 }
     195             :             }
     196         567 :         }
     197             :     }
     198             : 
     199        1134 :     Reference< XSimpleText > xText( xIface, UNO_QUERY );
     200             : 
     201         567 :     if( xText.is() )
     202         567 :         return xText->getString().getLength();
     203             : 
     204        2538 :     return false;
     205             : }
     206             : 
     207          44 : ShapeExport& ShapeExport::WriteBezierShape( Reference< XShape > xShape, bool bClosed )
     208             : {
     209             :     SAL_INFO("oox.shape", "write open bezier shape");
     210             : 
     211          44 :     FSHelperPtr pFS = GetFS();
     212          44 :     pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
     213             : 
     214          88 :     tools::PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
     215          44 :     Rectangle aRect( aPolyPolygon.GetBoundRect() );
     216             : 
     217             : #if OSL_DEBUG_LEVEL > 0
     218             :     awt::Size size = MapSize( awt::Size( aRect.GetWidth(), aRect.GetHeight() ) );
     219             :     SAL_INFO("oox.shape", "poly count " << aPolyPolygon.Count());
     220             :     SAL_INFO("oox.shape", "size: " << size.Width << " x " << size.Height);
     221             : #endif
     222             : 
     223             :     // non visual shape properties
     224          44 :     if (GetDocumentType() != DOCUMENT_DOCX)
     225             :     {
     226           0 :         pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
     227             :         pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     228             :                               XML_id, I32S( GetNewShapeID( xShape ) ),
     229           0 :                               XML_name, IDS( Freeform ),
     230           0 :                               FSEND );
     231             :     }
     232          44 :     pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
     233          44 :     if (GetDocumentType() != DOCUMENT_DOCX)
     234             :     {
     235           0 :         WriteNonVisualProperties( xShape );
     236           0 :         pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
     237             :     }
     238             : 
     239             :     // visual shape properties
     240          44 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     241          44 :     WriteTransformation( aRect, XML_a );
     242          44 :     WritePolyPolygon( aPolyPolygon );
     243          88 :     Reference< XPropertySet > xProps( xShape, UNO_QUERY );
     244          44 :     if( xProps.is() ) {
     245          44 :         if( bClosed )
     246          43 :             WriteFill( xProps );
     247          44 :         WriteOutline( xProps );
     248             :     }
     249             : 
     250          44 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
     251             : 
     252             :     // write text
     253          44 :     WriteTextBox( xShape, mnXmlNamespace );
     254             : 
     255          44 :     pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
     256             : 
     257          88 :     return *this;
     258             : }
     259             : 
     260          43 : ShapeExport& ShapeExport::WriteClosedBezierShape( Reference< XShape > xShape )
     261             : {
     262          43 :     return WriteBezierShape( xShape, true );
     263             : }
     264             : 
     265           1 : ShapeExport& ShapeExport::WriteOpenBezierShape( Reference< XShape > xShape )
     266             : {
     267           1 :     return WriteBezierShape( xShape, false );
     268             : }
     269             : 
     270          38 : ShapeExport& ShapeExport::WriteGroupShape(uno::Reference<drawing::XShape> xShape)
     271             : {
     272          38 :     FSHelperPtr pFS = GetFS();
     273          38 :     bool bToplevel = !m_xParent.is();
     274          38 :     if (!bToplevel)
     275           9 :         mnXmlNamespace = XML_wpg;
     276          38 :     pFS->startElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp), FSEND);
     277             : 
     278             :     // non visual properties
     279          38 :     pFS->singleElementNS(mnXmlNamespace, XML_cNvGrpSpPr, FSEND);
     280             : 
     281             :     // visual properties
     282          38 :     pFS->startElementNS(mnXmlNamespace, XML_grpSpPr, FSEND);
     283          38 :     WriteShapeTransformation(xShape, XML_a);
     284          38 :     pFS->endElementNS(mnXmlNamespace, XML_grpSpPr);
     285             : 
     286          76 :     uno::Reference<drawing::XShapes> xGroupShape(xShape, uno::UNO_QUERY_THROW);
     287          76 :     uno::Reference<drawing::XShape> xParent = m_xParent;
     288          38 :     m_xParent = xShape;
     289         496 :     for (sal_Int32 i = 0; i < xGroupShape->getCount(); ++i)
     290             :     {
     291         458 :         uno::Reference<drawing::XShape> xChild(xGroupShape->getByIndex(i), uno::UNO_QUERY_THROW);
     292         458 :         sal_Int32 nSavedNamespace = mnXmlNamespace;
     293             : 
     294         916 :         uno::Reference<lang::XServiceInfo> xServiceInfo(xChild, uno::UNO_QUERY_THROW);
     295         458 :         if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
     296           8 :             mnXmlNamespace = XML_pic;
     297             :         else
     298         450 :             mnXmlNamespace = XML_wps;
     299         458 :         WriteShape(xChild);
     300             : 
     301         458 :         mnXmlNamespace = nSavedNamespace;
     302         458 :     }
     303          38 :     m_xParent = xParent;
     304             : 
     305          38 :     pFS->endElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp));
     306          76 :     return *this;
     307             : }
     308             : 
     309         102 : static bool lcl_IsOnBlacklist(OUString& rShapeType)
     310             : {
     311             : #if !HAVE_BROKEN_STATIC_INITILIZER_LIST
     312             :     static
     313             : #endif
     314             :     const std::initializer_list<OUStringLiteral> vBlacklist = {
     315             :         OUStringLiteral("ellipse"),
     316             :         OUStringLiteral("ring"),
     317             :         OUStringLiteral("can"),
     318             :         OUStringLiteral("cube"),
     319             :         OUStringLiteral("paper"),
     320             :         OUStringLiteral("frame"),
     321             :         OUStringLiteral("smiley"),
     322             :         OUStringLiteral("sun"),
     323             :         OUStringLiteral("flower"),
     324             :         OUStringLiteral("forbidden"),
     325             :         OUStringLiteral("bracket-pair"),
     326             :         OUStringLiteral("brace-pair"),
     327             :         OUStringLiteral("col-60da8460"),
     328             :         OUStringLiteral("col-502ad400"),
     329             :         OUStringLiteral("quad-bevel"),
     330             :         OUStringLiteral("cloud-callout"),
     331             :         OUStringLiteral("line-callout-1"),
     332             :         OUStringLiteral("line-callout-2"),
     333             :         OUStringLiteral("line-callout-3"),
     334             :         OUStringLiteral("paper"),
     335             :         OUStringLiteral("vertical-scroll"),
     336             :         OUStringLiteral("horizontal-scroll"),
     337             :         OUStringLiteral("mso-spt34"),
     338             :         OUStringLiteral("mso-spt75"),
     339             :         OUStringLiteral("mso-spt164"),
     340             :         OUStringLiteral("mso-spt180"),
     341             :         OUStringLiteral("flowchart-process"),
     342             :         OUStringLiteral("flowchart-alternate-process"),
     343             :         OUStringLiteral("flowchart-decision"),
     344             :         OUStringLiteral("flowchart-data"),
     345             :         OUStringLiteral("flowchart-predefined-process"),
     346             :         OUStringLiteral("flowchart-internal-storage"),
     347             :         OUStringLiteral("flowchart-document"),
     348             :         OUStringLiteral("flowchart-multidocument"),
     349             :         OUStringLiteral("flowchart-terminator"),
     350             :         OUStringLiteral("flowchart-preparation"),
     351             :         OUStringLiteral("flowchart-manual-input"),
     352             :         OUStringLiteral("flowchart-manual-operation"),
     353             :         OUStringLiteral("flowchart-connector"),
     354             :         OUStringLiteral("flowchart-off-page-connector"),
     355             :         OUStringLiteral("flowchart-card"),
     356             :         OUStringLiteral("flowchart-punched-tape"),
     357             :         OUStringLiteral("flowchart-summing-junction"),
     358             :         OUStringLiteral("flowchart-or"),
     359             :         OUStringLiteral("flowchart-collate"),
     360             :         OUStringLiteral("flowchart-sort"),
     361             :         OUStringLiteral("flowchart-extract"),
     362             :         OUStringLiteral("flowchart-merge"),
     363             :         OUStringLiteral("flowchart-stored-data"),
     364             :         OUStringLiteral("flowchart-delay"),
     365             :         OUStringLiteral("flowchart-sequential-access"),
     366             :         OUStringLiteral("flowchart-magnetic-disk"),
     367             :         OUStringLiteral("flowchart-direct-access-storage"),
     368             :         OUStringLiteral("flowchart-display")
     369         102 :     };
     370             : 
     371         102 :     return std::find(vBlacklist.begin(), vBlacklist.end(), rShapeType) != vBlacklist.end();
     372             : }
     373             : 
     374         102 : static bool lcl_IsOnWhitelist(OUString& rShapeType)
     375             : {
     376             : #if !HAVE_BROKEN_STATIC_INITILIZER_LIST
     377             :     static
     378             : #endif
     379             :     const std::initializer_list<OUStringLiteral> vWhitelist = {
     380             :         OUStringLiteral("heart"),
     381             :         OUStringLiteral("puzzle")
     382         102 :     };
     383             : 
     384         102 :     return std::find(vWhitelist.begin(), vWhitelist.end(), rShapeType) != vWhitelist.end();
     385             : }
     386             : 
     387             : 
     388         413 : ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
     389             : {
     390             :     SAL_INFO("oox.shape", "write custom shape");
     391             : 
     392         413 :     Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
     393         413 :     bool bPredefinedHandlesUsed = true;
     394         413 :     bool bHasHandles = false;
     395         826 :     OUString sShapeType;
     396         413 :     sal_uInt32 nMirrorFlags = 0;
     397         413 :     MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( xShape, nMirrorFlags, sShapeType );
     398         413 :     SdrObjCustomShape* pShape = static_cast<SdrObjCustomShape*>( GetSdrObjectFromXShape( xShape ) );
     399         413 :     bool bIsDefaultObject = EscherPropertyContainer::IsDefaultObject( pShape, eShapeType );
     400         413 :     const char* sPresetShape = msfilter::util::GetOOXMLPresetGeometry( USS( sShapeType ) );
     401             :     SAL_INFO("oox.shape", "custom shape type: " << sShapeType << " ==> " << sPresetShape);
     402         826 :     Sequence< PropertyValue > aGeometrySeq;
     403         413 :     sal_Int32 nAdjustmentValuesIndex = -1;
     404             : 
     405         413 :     bool bFlipH = false;
     406         413 :     bool bFlipV = false;
     407             : 
     408         413 :     if( GETA( CustomShapeGeometry ) ) {
     409             :         SAL_INFO("oox.shape", "got custom shape geometry");
     410         413 :         if( mAny >>= aGeometrySeq ) {
     411             : 
     412             :             SAL_INFO("oox.shape", "got custom shape geometry sequence");
     413        4134 :             for( int i = 0; i < aGeometrySeq.getLength(); i++ ) {
     414        3721 :                 const PropertyValue& rProp = aGeometrySeq[ i ];
     415             :                 SAL_INFO("oox.shape", "geometry property: " << rProp.Name);
     416             : 
     417        3721 :                 if ( rProp.Name == "MirroredX" )
     418         364 :                     rProp.Value >>= bFlipH;
     419             : 
     420        3721 :                 if ( rProp.Name == "MirroredY" )
     421         366 :                     rProp.Value >>= bFlipV;
     422        3721 :                 if ( rProp.Name == "AdjustmentValues" )
     423         413 :                     nAdjustmentValuesIndex = i;
     424        3308 :                 else if ( rProp.Name == "Handles" )
     425             :                 {
     426         326 :                     uno::Sequence<beans::PropertyValue> aHandles;
     427         326 :                     rProp.Value >>= aHandles;
     428         326 :                     if ( aHandles.getLength() )
     429           0 :                         bHasHandles = true;
     430         326 :                     if( !bIsDefaultObject )
     431         311 :                         bPredefinedHandlesUsed = false;
     432             :                     // TODO: update nAdjustmentsWhichNeedsToBeConverted here
     433             :                 }
     434        2982 :                 else if ( rProp.Name == "PresetTextWarp" )
     435             :                 {
     436          33 :                     rProp.Value >>= m_presetWarp;
     437             :                 }
     438             :             }
     439             :         }
     440             :     }
     441             : 
     442         826 :     FSHelperPtr pFS = GetFS();
     443         413 :     pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
     444             : 
     445             :     // non visual shape properties
     446         413 :     if (GetDocumentType() != DOCUMENT_DOCX)
     447             :     {
     448          35 :         bool isVisible = true ;
     449          35 :         if( GETA (Visible))
     450             :         {
     451          35 :             mAny >>= isVisible;
     452             :         }
     453          35 :         pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
     454             :         pFS->startElementNS( mnXmlNamespace, XML_cNvPr,
     455             :                 XML_id, I32S( GetNewShapeID( xShape ) ),
     456          70 :                 XML_name, IDS( CustomShape ),
     457             :                 XML_hidden, isVisible ? NULL : "1",
     458          70 :                 FSEND );
     459             : 
     460          35 :         if( GETA( URL ) )
     461             :         {
     462          10 :             OUString sURL;
     463          10 :             mAny >>= sURL;
     464          10 :             if( !sURL.isEmpty() )
     465             :             {
     466             :                 OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(),
     467             :                         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
     468           3 :                         mpURLTransformer->getTransformedString(sURL),
     469           6 :                         mpURLTransformer->isExternalURL(sURL));
     470             : 
     471             :                 mpFS->singleElementNS( XML_a, XML_hlinkClick,
     472             :                         FSNS( XML_r,XML_id ), USS( sRelId ),
     473           3 :                         FSEND );
     474          10 :             }
     475             :         }
     476          35 :         pFS->endElementNS(mnXmlNamespace, XML_cNvPr);
     477          35 :         pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
     478          35 :         WriteNonVisualProperties( xShape );
     479          35 :         pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
     480             :     }
     481             :     else
     482         378 :         pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, FSEND);
     483             : 
     484             :     // visual shape properties
     485         413 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     486             :     // moon is flipped in MSO, and mso-spt89 (right up arrow) is mapped to leftUpArrow
     487         413 :     if ( sShapeType == "moon" || sShapeType == "mso-spt89" )
     488           0 :         WriteShapeTransformation( xShape, XML_a, !bFlipH, bFlipV, false);
     489             :     else
     490         413 :         WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false);
     491             : 
     492             :     // we export non-primitive shapes to custom geometry
     493             :     // we also export non-ooxml shapes which have handles/equations to custom geometry, because
     494             :     // we cannot convert ODF equations to DrawingML equations. TODO: see what binary DOC export filter does.
     495             :     // but our WritePolyPolygon() function is incomplete, therefore we use a blacklist
     496             :     // we use a whitelist for shapes where mapping to MSO preset shape is not optimal
     497         413 :     bool bCustGeom = true;
     498         413 :     if( sShapeType == "ooxml-non-primitive" )
     499          26 :         bCustGeom = true;
     500         387 :     else if( sShapeType.startsWith("ooxml") )
     501         285 :         bCustGeom = false;
     502         102 :     else if( lcl_IsOnWhitelist(sShapeType) )
     503           0 :         bCustGeom = true;
     504         102 :     else if( lcl_IsOnBlacklist(sShapeType) )
     505          13 :         bCustGeom = false;
     506          89 :     else if( bHasHandles )
     507           0 :         bCustGeom = true;
     508             : 
     509         413 :     if (bHasHandles && bCustGeom && pShape)
     510             :     {
     511           0 :         WritePolyPolygon( tools::PolyPolygon( pShape->GetLineGeometry(true) ) );
     512             :     }
     513         413 :     else if (bCustGeom && pShape)
     514             :     {
     515         115 :         WriteCustomGeometry( xShape );
     516             :     }
     517             :     else // preset geometry
     518             :     {
     519         298 :         if( nAdjustmentValuesIndex != -1 )
     520             :         {
     521         298 :             sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
     522             :             WritePresetShape( sPresetShape, eShapeType, bPredefinedHandlesUsed,
     523         298 :                               nAdjustmentsWhichNeedsToBeConverted, aGeometrySeq[ nAdjustmentValuesIndex ] );
     524             :         }
     525             :         else
     526           0 :             WritePresetShape( sPresetShape );
     527             :     }
     528         413 :     if( rXPropSet.is() )
     529             :     {
     530         413 :         WriteFill( rXPropSet );
     531         413 :         WriteOutline( rXPropSet );
     532         413 :         WriteShapeEffects( rXPropSet );
     533         413 :         WriteShape3DEffects( rXPropSet );
     534             :     }
     535             : 
     536         413 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
     537             : 
     538         413 :     pFS->startElementNS( mnXmlNamespace, XML_style, FSEND );
     539         413 :     WriteShapeStyle( rXPropSet );
     540         413 :     pFS->endElementNS( mnXmlNamespace, XML_style );
     541             : 
     542             :     // write text
     543         413 :     WriteTextBox( xShape, mnXmlNamespace );
     544             : 
     545         413 :     pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
     546             : 
     547         826 :     return *this;
     548             : }
     549             : 
     550           0 : ShapeExport& ShapeExport::WriteEllipseShape( Reference< XShape > xShape )
     551             : {
     552             :     SAL_INFO("oox.shape", "write ellipse shape");
     553             : 
     554           0 :     FSHelperPtr pFS = GetFS();
     555             : 
     556           0 :     pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
     557             : 
     558             :     // TODO: arc, section, cut, connector
     559             : 
     560             :     // non visual shape properties
     561           0 :     if (GetDocumentType() != DOCUMENT_DOCX)
     562             :     {
     563           0 :         pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
     564             :         pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     565             :                 XML_id, I32S( GetNewShapeID( xShape ) ),
     566           0 :                 XML_name, IDS( Ellipse ),
     567           0 :                 FSEND );
     568           0 :         pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
     569           0 :         WriteNonVisualProperties( xShape );
     570           0 :         pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
     571             :     }
     572             :     else
     573           0 :         pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, FSEND);
     574             : 
     575             :     // visual shape properties
     576           0 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     577           0 :     WriteShapeTransformation( xShape, XML_a, false, false, false);
     578           0 :     WritePresetShape( "ellipse" );
     579           0 :     Reference< XPropertySet > xProps( xShape, UNO_QUERY );
     580           0 :     if( xProps.is() )
     581             :     {
     582           0 :         WriteFill( xProps );
     583           0 :         WriteOutline( xProps );
     584             :     }
     585           0 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
     586             : 
     587             :     // write text
     588           0 :     WriteTextBox( xShape, mnXmlNamespace );
     589             : 
     590           0 :     pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
     591             : 
     592           0 :     return *this;
     593             : }
     594             : 
     595         110 : ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape )
     596             : {
     597         110 :     WriteGraphicObjectShapePart( xShape );
     598             : 
     599         110 :     return *this;
     600             : }
     601             : 
     602         110 : void ShapeExport::WriteGraphicObjectShapePart( Reference< XShape > xShape, const Graphic* pGraphic )
     603             : {
     604             :     SAL_INFO("oox.shape", "write graphic object shape");
     605             : 
     606         110 :     if( NonEmptyText( xShape ) )
     607             :     {
     608             :         // avoid treating all 'IsPresentationObject' objects as having text.
     609          54 :         Reference< XSimpleText > xText( xShape, UNO_QUERY );
     610             : 
     611          54 :         if( xText.is() && xText->getString().getLength() )
     612             :         {
     613             :             SAL_INFO("oox.shape", "graphicObject: wrote only text");
     614             : 
     615           0 :             WriteTextShape( xShape );
     616             : 
     617             :             //DBG(dump_pset(mXPropSet));
     618           0 :             return;
     619          54 :         }
     620             :     }
     621             : 
     622             :     SAL_INFO("oox.shape", "graphicObject without text");
     623             : 
     624         110 :     OUString sGraphicURL;
     625         220 :     Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
     626         110 :     if( !pGraphic && ( !xShapeProps.is() || !( xShapeProps->getPropertyValue( "GraphicURL" ) >>= sGraphicURL ) ) )
     627             :     {
     628             :         SAL_INFO("oox.shape", "no graphic URL found");
     629           0 :         return;
     630             :     }
     631             : 
     632         220 :     FSHelperPtr pFS = GetFS();
     633             : 
     634         110 :     if (GetDocumentType() != DOCUMENT_DOCX)
     635          68 :         pFS->startElementNS( mnXmlNamespace, XML_pic, FSEND );
     636             :     else
     637             :         pFS->startElementNS( mnXmlNamespace, XML_pic,
     638             :                              FSNS(XML_xmlns, XML_pic), "http://schemas.openxmlformats.org/drawingml/2006/picture",
     639          42 :                              FSEND );
     640             : 
     641         110 :     pFS->startElementNS( mnXmlNamespace, XML_nvPicPr, FSEND );
     642             : 
     643         220 :     OUString sName, sDescr;
     644             :     bool bHaveName, bHaveDesc;
     645             : 
     646         110 :     if ( ( bHaveName= GetProperty( xShapeProps, "Name" ) ) )
     647         110 :         mAny >>= sName;
     648         110 :     if ( ( bHaveDesc = GetProperty( xShapeProps, "Description" ) ) )
     649         110 :         mAny >>= sDescr;
     650             : 
     651             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     652             :                           XML_id,     I32S( GetNewShapeID( xShape ) ),
     653         220 :                           XML_name,   bHaveName ? USS( sName ) : OString( "Picture " + OString::number( mnPictureIdMax++ )).getStr(),
     654         330 :                           XML_descr,  bHaveDesc ? USS( sDescr ) : NULL,
     655         330 :                           FSEND );
     656             :     // OOXTODO: //cNvPr children: XML_extLst, XML_hlinkClick, XML_hlinkHover
     657             : 
     658             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvPicPr,
     659             :                           // OOXTODO: XML_preferRelativeSize
     660         110 :                           FSEND );
     661             : 
     662         110 :     WriteNonVisualProperties( xShape );
     663             : 
     664         110 :     pFS->endElementNS( mnXmlNamespace, XML_nvPicPr );
     665             : 
     666         110 :     pFS->startElementNS( mnXmlNamespace, XML_blipFill, FSEND );
     667             : 
     668         110 :     WriteBlip( xShapeProps, sGraphicURL, false, pGraphic );
     669             : 
     670         110 :     WriteSrcRect( xShapeProps, sGraphicURL );
     671             : 
     672             :     // now we stretch always when we get pGraphic (when changing that
     673             :     // behavior, test n#780830 for regression, where the OLE sheet might get tiled
     674         110 :     bool bStretch = false;
     675         110 :     if( !pGraphic && GetProperty( xShapeProps, "FillBitmapStretch" ) )
     676         110 :         mAny >>= bStretch;
     677             : 
     678         110 :     if ( pGraphic || bStretch )
     679         110 :         pFS->singleElementNS( XML_a, XML_stretch, FSEND );
     680             : 
     681         110 :     pFS->endElementNS( mnXmlNamespace, XML_blipFill );
     682             : 
     683             :     // visual shape properties
     684         110 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     685         110 :     WriteShapeTransformation( xShape, XML_a, false, false, false);
     686         110 :     WritePresetShape( "rect" );
     687             :     // graphic object can come with the frame (bnc#654525)
     688         110 :     WriteOutline( xShapeProps );
     689             : 
     690         110 :     WriteShapeEffects( xShapeProps );
     691         110 :     WriteShape3DEffects( xShapeProps );
     692             : 
     693         110 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
     694             : 
     695         220 :     pFS->endElementNS( mnXmlNamespace, XML_pic );
     696             : }
     697             : 
     698           0 : ShapeExport& ShapeExport::WriteConnectorShape( Reference< XShape > xShape )
     699             : {
     700           0 :     bool bFlipH = false;
     701           0 :     bool bFlipV = false;
     702             : 
     703             :     SAL_INFO("oox.shape", "write connector shape");
     704             : 
     705           0 :     FSHelperPtr pFS = GetFS();
     706             : 
     707           0 :     const char* sGeometry = "line";
     708           0 :     Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
     709           0 :     Reference< XPropertyState > rXPropState( xShape, UNO_QUERY );
     710           0 :     awt::Point aStartPoint, aEndPoint;
     711           0 :     Reference< XShape > rXShapeA;
     712           0 :     Reference< XShape > rXShapeB;
     713             :     PropertyState eState;
     714             :     ConnectorType eConnectorType;
     715           0 :     if( GETAD( EdgeKind ) ) {
     716           0 :         mAny >>= eConnectorType;
     717             : 
     718           0 :         switch( eConnectorType ) {
     719             :             case ConnectorType_CURVE:
     720           0 :                 sGeometry = "curvedConnector3";
     721           0 :                 break;
     722             :             case ConnectorType_STANDARD:
     723           0 :                 sGeometry = "bentConnector3";
     724           0 :                 break;
     725             :             default:
     726             :             case ConnectorType_LINE:
     727             :             case ConnectorType_LINES:
     728           0 :                 sGeometry = "straightConnector1";
     729           0 :                 break;
     730             :         }
     731             : 
     732           0 :         if( GETAD( EdgeStartPoint ) ) {
     733           0 :             mAny >>= aStartPoint;
     734           0 :             if( GETAD( EdgeEndPoint ) ) {
     735           0 :                 mAny >>= aEndPoint;
     736             :             }
     737             :         }
     738           0 :         GET( rXShapeA, EdgeStartConnection );
     739           0 :         GET( rXShapeB, EdgeEndConnection );
     740             :     }
     741           0 :     EscherConnectorListEntry aConnectorEntry( xShape, aStartPoint, rXShapeA, aEndPoint, rXShapeB );
     742             : 
     743           0 :     Rectangle aRect( Point( aStartPoint.X, aStartPoint.Y ), Point( aEndPoint.X, aEndPoint.Y ) );
     744           0 :     if( aRect.getWidth() < 0 ) {
     745           0 :         bFlipH = true;
     746           0 :         aRect.setX( aEndPoint.X );
     747           0 :         aRect.setWidth( aStartPoint.X - aEndPoint.X );
     748             :     }
     749             : 
     750           0 :     if( aRect.getHeight() < 0 ) {
     751           0 :         bFlipV = true;
     752           0 :         aRect.setY( aEndPoint.Y );
     753           0 :         aRect.setHeight( aStartPoint.Y - aEndPoint.Y );
     754             :     }
     755             : 
     756           0 :     pFS->startElementNS( mnXmlNamespace, XML_cxnSp, FSEND );
     757             : 
     758             :     // non visual shape properties
     759           0 :     pFS->startElementNS( mnXmlNamespace, XML_nvCxnSpPr, FSEND );
     760             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     761             :                           XML_id, I32S( GetNewShapeID( xShape ) ),
     762           0 :                           XML_name, IDS( Line ),
     763           0 :                           FSEND );
     764             :     // non visual connector shape drawing properties
     765           0 :     pFS->startElementNS( mnXmlNamespace, XML_cNvCxnSpPr, FSEND );
     766           0 :     WriteConnectorConnections( aConnectorEntry, GetShapeID( rXShapeA ), GetShapeID( rXShapeB ) );
     767           0 :     pFS->endElementNS( mnXmlNamespace, XML_cNvCxnSpPr );
     768           0 :     pFS->singleElementNS( mnXmlNamespace, XML_nvPr, FSEND );
     769           0 :     pFS->endElementNS( mnXmlNamespace, XML_nvCxnSpPr );
     770             : 
     771             :     // visual shape properties
     772           0 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     773           0 :     WriteTransformation( aRect, XML_a, bFlipH, bFlipV );
     774             :     // TODO: write adjustments (ppt export doesn't work well there either)
     775           0 :     WritePresetShape( sGeometry );
     776           0 :     Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
     777           0 :     if( xShapeProps.is() )
     778           0 :         WriteOutline( xShapeProps );
     779           0 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
     780             : 
     781             :     // write text
     782           0 :     WriteTextBox( xShape, mnXmlNamespace );
     783             : 
     784           0 :     pFS->endElementNS( mnXmlNamespace, XML_cxnSp );
     785             : 
     786           0 :     return *this;
     787             : }
     788             : 
     789          16 : ShapeExport& ShapeExport::WriteLineShape( Reference< XShape > xShape )
     790             : {
     791          16 :     bool bFlipH = false;
     792          16 :     bool bFlipV = false;
     793             : 
     794             :     SAL_INFO("oox.shape", "write line shape");
     795             : 
     796          16 :     FSHelperPtr pFS = GetFS();
     797             : 
     798          16 :     pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
     799             : 
     800          32 :     tools::PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
     801          16 :     if( aPolyPolygon.Count() == 1 && aPolyPolygon[ 0 ].GetSize() == 2)
     802             :     {
     803          16 :         const Polygon& rPoly = aPolyPolygon[ 0 ];
     804             : 
     805          16 :         bFlipH = ( rPoly[ 0 ].X() > rPoly[ 1 ].X() );
     806          16 :         bFlipV = ( rPoly[ 0 ].Y() > rPoly[ 1 ].Y() );
     807             :     }
     808             : 
     809             :     // non visual shape properties
     810          16 :     if (GetDocumentType() != DOCUMENT_DOCX)
     811             :     {
     812           1 :         pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
     813             :         pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     814             :                               XML_id, I32S( GetNewShapeID( xShape ) ),
     815           2 :                               XML_name, IDS( Line ),
     816           1 :                               FSEND );
     817             :     }
     818          16 :     pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
     819          16 :     if (GetDocumentType() != DOCUMENT_DOCX)
     820             :     {
     821           1 :         WriteNonVisualProperties( xShape );
     822           1 :         pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
     823             :     }
     824             : 
     825             :     // visual shape properties
     826          16 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     827          16 :     WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, true);
     828          16 :     WritePresetShape( "line" );
     829          32 :     Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
     830          16 :     if( xShapeProps.is() )
     831          16 :         WriteOutline( xShapeProps );
     832          16 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
     833             : 
     834             :     //write style
     835          16 :     pFS->startElementNS( mnXmlNamespace, XML_style, FSEND );
     836          16 :     WriteShapeStyle( xShapeProps );
     837          16 :     pFS->endElementNS( mnXmlNamespace, XML_style );
     838             : 
     839             :     // write text
     840          16 :     WriteTextBox( xShape, mnXmlNamespace );
     841             : 
     842          16 :     pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
     843             : 
     844          32 :     return *this;
     845             : }
     846             : 
     847         968 : ShapeExport& ShapeExport::WriteNonVisualDrawingProperties( Reference< XShape > xShape, const char* pName )
     848             : {
     849             :     GetFS()->singleElementNS( mnXmlNamespace, XML_cNvPr,
     850             :                               XML_id, I32S( GetNewShapeID( xShape ) ),
     851             :                               XML_name, pName,
     852         968 :                               FSEND );
     853             : 
     854         968 :     return *this;
     855             : }
     856             : 
     857         113 : ShapeExport& ShapeExport::WriteNonVisualProperties( Reference< XShape > )
     858             : {
     859             :     // Override to generate //nvPr elements.
     860         113 :     return *this;
     861             : }
     862             : 
     863          50 : ShapeExport& ShapeExport::WriteRectangleShape( Reference< XShape > xShape )
     864             : {
     865             :     SAL_INFO("oox.shape", "write rectangle shape");
     866             : 
     867          50 :     FSHelperPtr pFS = GetFS();
     868             : 
     869          50 :     pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
     870             : 
     871          50 :     sal_Int32 nRadius = 0;
     872             : 
     873         100 :     Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
     874          50 :     if( xShapeProps.is() )
     875             :     {
     876          50 :         xShapeProps->getPropertyValue( "CornerRadius" ) >>= nRadius;
     877             :     }
     878             : 
     879          50 :     if( nRadius )
     880             :     {
     881           0 :         nRadius = MapSize( awt::Size( nRadius, 0 ) ).Width;
     882             :     }
     883             : 
     884             :     // non visual shape properties
     885          50 :     if (GetDocumentType() == DOCUMENT_DOCX)
     886          49 :         pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
     887          50 :     pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
     888             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
     889             :                           XML_id, I32S( GetNewShapeID( xShape ) ),
     890         100 :                           XML_name, IDS( Rectangle ),
     891          50 :                           FSEND );
     892          50 :     pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
     893          50 :     WriteNonVisualProperties( xShape );
     894          50 :     pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
     895             : 
     896             :     // visual shape properties
     897          50 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     898          50 :     WriteShapeTransformation( xShape, XML_a, false, false, false);
     899          50 :     WritePresetShape( "rect" );
     900         100 :     Reference< XPropertySet > xProps( xShape, UNO_QUERY );
     901          50 :     if( xProps.is() )
     902             :     {
     903          50 :         WriteFill( xProps );
     904          50 :         WriteOutline( xProps );
     905             :     }
     906          50 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
     907             : 
     908             :     // write text
     909          50 :     WriteTextBox( xShape, mnXmlNamespace );
     910             : 
     911          50 :     pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
     912             : 
     913         100 :     return *this;
     914             : }
     915             : 
     916             : typedef ShapeExport& (ShapeExport::*ShapeConverter)( Reference< XShape > );
     917             : typedef std::unordered_map< const char*, ShapeConverter, rtl::CStringHash, rtl::CStringEqual> NameToConvertMapType;
     918             : 
     919        3774 : static const NameToConvertMapType& lcl_GetConverters(DrawingML::DocumentType eDocumentType)
     920             : {
     921             :     static bool shape_map_inited = false;
     922        3774 :     static NameToConvertMapType shape_converters;
     923        3774 :     if( shape_map_inited )
     924             :     {
     925        3760 :         return shape_converters;
     926             :     }
     927             : 
     928          14 :     shape_converters[ "com.sun.star.drawing.ClosedBezierShape" ]        = &ShapeExport::WriteClosedBezierShape;
     929          14 :     shape_converters[ "com.sun.star.drawing.ConnectorShape" ]           = &ShapeExport::WriteConnectorShape;
     930          14 :     shape_converters[ "com.sun.star.drawing.CustomShape" ]              = &ShapeExport::WriteCustomShape;
     931          14 :     shape_converters[ "com.sun.star.drawing.EllipseShape" ]             = &ShapeExport::WriteEllipseShape;
     932          14 :     shape_converters[ "com.sun.star.drawing.GraphicObjectShape" ]       = &ShapeExport::WriteGraphicObjectShape;
     933          14 :     shape_converters[ "com.sun.star.drawing.LineShape" ]                = &ShapeExport::WriteLineShape;
     934          14 :     shape_converters[ "com.sun.star.drawing.OpenBezierShape" ]          = &ShapeExport::WriteOpenBezierShape;
     935          14 :     shape_converters[ "com.sun.star.drawing.RectangleShape" ]           = &ShapeExport::WriteRectangleShape;
     936          14 :     shape_converters[ "com.sun.star.drawing.OLE2Shape" ]                = &ShapeExport::WriteOLE2Shape;
     937          14 :     shape_converters[ "com.sun.star.drawing.TableShape" ]               = &ShapeExport::WriteTableShape;
     938          14 :     shape_converters[ "com.sun.star.drawing.TextShape" ]                = &ShapeExport::WriteTextShape;
     939             : 
     940          14 :     shape_converters[ "com.sun.star.presentation.GraphicObjectShape" ]  = &ShapeExport::WriteGraphicObjectShape;
     941          14 :     shape_converters[ "com.sun.star.presentation.OLE2Shape" ]           = &ShapeExport::WriteOLE2Shape;
     942          14 :     shape_converters[ "com.sun.star.presentation.TableShape" ]          = &ShapeExport::WriteTableShape;
     943          14 :     shape_converters[ "com.sun.star.presentation.TextShape" ]           = &ShapeExport::WriteTextShape;
     944             : 
     945          14 :     shape_converters[ "com.sun.star.presentation.DateTimeShape" ]       = &ShapeExport::WriteTextShape;
     946          14 :     shape_converters[ "com.sun.star.presentation.FooterShape" ]         = &ShapeExport::WriteTextShape;
     947          14 :     shape_converters[ "com.sun.star.presentation.HeaderShape" ]         = &ShapeExport::WriteTextShape;
     948          14 :     shape_converters[ "com.sun.star.presentation.NotesShape" ]          = &ShapeExport::WriteTextShape;
     949          14 :     shape_converters[ "com.sun.star.presentation.OutlinerShape" ]       = &ShapeExport::WriteTextShape;
     950          14 :     shape_converters[ "com.sun.star.presentation.SlideNumberShape" ]    = &ShapeExport::WriteTextShape;
     951          14 :     shape_converters[ "com.sun.star.presentation.TitleTextShape" ]      = &ShapeExport::WriteTextShape;
     952          14 :     if (eDocumentType == DrawingML::DOCUMENT_DOCX)
     953          11 :         shape_converters[ "com.sun.star.drawing.GroupShape" ] = &ShapeExport::WriteGroupShape;
     954          14 :     shape_map_inited = true;
     955             : 
     956          14 :     return shape_converters;
     957             : }
     958             : 
     959        1887 : ShapeExport& ShapeExport::WriteShape( Reference< XShape > xShape )
     960             : {
     961        1887 :     OUString sShapeType = xShape->getShapeType();
     962             :     SAL_INFO("oox.shape", "write shape: " << sShapeType);
     963        1887 :     NameToConvertMapType::const_iterator aConverter = lcl_GetConverters(GetDocumentType()).find( USS( sShapeType ) );
     964        1887 :     if( aConverter == lcl_GetConverters(GetDocumentType()).end() )
     965             :     {
     966             :         SAL_INFO("oox.shape", "unknown shape");
     967         222 :         return WriteUnknownShape( xShape );
     968             :     }
     969        1665 :     (this->*(aConverter->second))( xShape );
     970             : 
     971        1665 :     return *this;
     972             : }
     973             : 
     974        1593 : ShapeExport& ShapeExport::WriteTextBox( Reference< XInterface > xIface, sal_Int32 nXmlNamespace )
     975             : {
     976             :     // In case this shape has an associated textbox, then export that, and we're done.
     977        1593 :     if (GetDocumentType() == DOCUMENT_DOCX && GetTextExport())
     978             :     {
     979         576 :         uno::Reference<beans::XPropertySet> xPropertySet(xIface, uno::UNO_QUERY);
     980         576 :         if (xPropertySet.is())
     981             :         {
     982         576 :             uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
     983         576 :             if (xPropertySetInfo->hasPropertyByName("TextBox") && xPropertySet->getPropertyValue("TextBox").get<bool>())
     984             :             {
     985         116 :                 GetTextExport()->WriteTextBox(uno::Reference<drawing::XShape>(xIface, uno::UNO_QUERY_THROW));
     986         116 :                 WriteText( xIface, m_presetWarp, /*bBodyPr=*/true, /*bText=*/false, /*nXmlNamespace=*/nXmlNamespace );
     987         116 :                 return *this;
     988         460 :             }
     989         460 :         }
     990             :     }
     991             : 
     992        1477 :     if( NonEmptyText( xIface ) )
     993             :     {
     994        1131 :         FSHelperPtr pFS = GetFS();
     995             : 
     996        1131 :         pFS->startElementNS( nXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_txBody : XML_txbx), FSEND );
     997        1131 :         WriteText( xIface, m_presetWarp, /*bBodyPr=*/(GetDocumentType() != DOCUMENT_DOCX), /*bText=*/true );
     998        1131 :         pFS->endElementNS( nXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_txBody : XML_txbx) );
     999        1131 :         if (GetDocumentType() == DOCUMENT_DOCX)
    1000         130 :             WriteText( xIface, m_presetWarp, /*bBodyPr=*/true, /*bText=*/false, /*nXmlNamespace=*/nXmlNamespace );
    1001             :     }
    1002         346 :     else if (GetDocumentType() == DOCUMENT_DOCX)
    1003         330 :         mpFS->singleElementNS(nXmlNamespace, XML_bodyPr, FSEND);
    1004             : 
    1005        1477 :     return *this;
    1006             : }
    1007             : 
    1008           4 : void ShapeExport::WriteTable( Reference< XShape > rXShape  )
    1009             : {
    1010             :     OSL_TRACE("write table");
    1011             : 
    1012           4 :     Reference< XTable > xTable;
    1013           8 :     Reference< XPropertySet > xPropSet( rXShape, UNO_QUERY );
    1014             : 
    1015           4 :     mpFS->startElementNS( XML_a, XML_graphic, FSEND );
    1016           4 :     mpFS->startElementNS( XML_a, XML_graphicData, XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/table", FSEND );
    1017             : 
    1018           4 :     if ( xPropSet.is() && ( xPropSet->getPropertyValue( "Model" ) >>= xTable ) )
    1019             :     {
    1020           4 :         mpFS->startElementNS( XML_a, XML_tbl, FSEND );
    1021           4 :         mpFS->singleElementNS( XML_a, XML_tblPr, FSEND );
    1022             : 
    1023           4 :         Reference< container::XIndexAccess > xColumns( xTable->getColumns(), UNO_QUERY_THROW );
    1024           8 :         Reference< container::XIndexAccess > xRows( xTable->getRows(), UNO_QUERY_THROW );
    1025           4 :         sal_uInt16 nRowCount = static_cast< sal_uInt16 >( xRows->getCount() );
    1026           4 :         sal_uInt16 nColumnCount = static_cast< sal_uInt16 >( xColumns->getCount() );
    1027             : 
    1028           4 :         mpFS->startElementNS( XML_a, XML_tblGrid, FSEND );
    1029             : 
    1030          12 :         for ( sal_Int32 x = 0; x < nColumnCount; x++ )
    1031             :         {
    1032           8 :             Reference< XPropertySet > xColPropSet( xColumns->getByIndex( x ), UNO_QUERY_THROW );
    1033           8 :             sal_Int32 nWidth(0);
    1034           8 :             xColPropSet->getPropertyValue( "Width" ) >>= nWidth;
    1035             : 
    1036           8 :             mpFS->singleElementNS( XML_a, XML_gridCol, XML_w, I64S(oox::drawingml::convertHmmToEmu(nWidth)), FSEND );
    1037           8 :         }
    1038             : 
    1039           4 :         mpFS->endElementNS( XML_a, XML_tblGrid );
    1040             : 
    1041             :         // map for holding the transpose index of the merged cells and pair<parentTransposeIndex, parentCell>
    1042             :         typedef std::unordered_map<sal_Int32, std::pair<sal_Int32, Reference< XMergeableCell> > > transposeTableMap;
    1043           8 :         transposeTableMap mergedCellMap;
    1044             : 
    1045          10 :         for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
    1046             :         {
    1047           6 :             Reference< XPropertySet > xRowPropSet( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
    1048           6 :             sal_Int32 nRowHeight(0);
    1049             : 
    1050           6 :             xRowPropSet->getPropertyValue( "Height" ) >>= nRowHeight;
    1051             : 
    1052           6 :             mpFS->startElementNS( XML_a, XML_tr, XML_h, I64S( oox::drawingml::convertHmmToEmu( nRowHeight ) ), FSEND );
    1053          18 :             for( sal_Int32 nColumn = 0; nColumn < nColumnCount; nColumn++ )
    1054             :             {
    1055          24 :                 Reference< XMergeableCell > xCell( xTable->getCellByPosition( nColumn, nRow ),
    1056          24 :                                                    UNO_QUERY_THROW );
    1057          12 :                 sal_Int32 transposedIndexofCell = (nRow * nColumnCount) + nColumn;
    1058             : 
    1059             :                 //assume we will open a cell, set to false below if we won't
    1060          12 :                 bool bCellOpened = true;
    1061             : 
    1062          12 :                 if(xCell->getColumnSpan() > 1 && xCell->getRowSpan() > 1)
    1063             :                 {
    1064             :                     // having both : horizontal and vertical merge
    1065             :                     mpFS->startElementNS(XML_a, XML_tc, XML_gridSpan,
    1066           0 :                                          I32S(xCell->getColumnSpan()),
    1067           0 :                                          XML_rowSpan, I32S(xCell->getRowSpan()),
    1068           0 :                                          FSEND);
    1069             :                     // since, XMergeableCell doesn't have the information about
    1070             :                     // cell having hMerge or vMerge.
    1071             :                     // So, Populating the merged cell map in-order to use it to
    1072             :                     // decide the attribute for the individual cell.
    1073           0 :                     for(sal_Int32 columnIndex = nColumn; columnIndex < nColumn+xCell->getColumnSpan(); ++columnIndex)
    1074             :                     {
    1075           0 :                         for(sal_Int32 rowIndex = nRow; rowIndex < nRow+xCell->getRowSpan(); ++rowIndex)
    1076             :                         {
    1077             :                             sal_Int32 transposeIndexForMergeCell =
    1078           0 :                                 (rowIndex * nColumnCount) + columnIndex;
    1079           0 :                             mergedCellMap[transposeIndexForMergeCell] =
    1080           0 :                                 std::make_pair(transposedIndexofCell, xCell);
    1081             :                         }
    1082             :                     }
    1083             : 
    1084             :                 }
    1085          12 :                 else if(xCell->getColumnSpan() > 1)
    1086             :                 {
    1087             :                     // having : horizontal merge
    1088             :                     mpFS->startElementNS(XML_a, XML_tc, XML_gridSpan,
    1089           0 :                                          I32S(xCell->getColumnSpan()), FSEND);
    1090           0 :                     for(sal_Int32 columnIndex = nColumn; columnIndex < xCell->getColumnSpan(); ++columnIndex) {
    1091           0 :                         sal_Int32 transposeIndexForMergeCell = (nRow*nColumnCount) + columnIndex;
    1092           0 :                         mergedCellMap[transposeIndexForMergeCell] =
    1093           0 :                             std::make_pair(transposedIndexofCell, xCell);
    1094             :                     }
    1095             :                 }
    1096          12 :                 else if(xCell->getRowSpan() > 1)
    1097             :                 {
    1098             :                     // having : vertical merge
    1099             :                     mpFS->startElementNS(XML_a, XML_tc, XML_rowSpan,
    1100           0 :                                          I32S(xCell->getRowSpan()), FSEND);
    1101             : 
    1102           0 :                     for(sal_Int32 rowIndex = nRow; rowIndex < xCell->getRowSpan(); ++rowIndex) {
    1103           0 :                         sal_Int32 transposeIndexForMergeCell = (rowIndex*nColumnCount) + nColumn;
    1104           0 :                         mergedCellMap[transposeIndexForMergeCell] =
    1105           0 :                             std::make_pair(transposedIndexofCell, xCell);
    1106             :                     }
    1107             :                 }
    1108             :                 else
    1109             :                 {
    1110             :                     // now, the cell can be an independent cell or
    1111             :                     // it can be a cell which is been merged to some parent cell
    1112          12 :                     if(!xCell->isMerged())
    1113             :                     {
    1114             :                         // independent cell
    1115          12 :                         mpFS->startElementNS( XML_a, XML_tc, FSEND );
    1116             :                     }
    1117             :                     else
    1118             :                     {
    1119             :                         // it a merged cell to some parent cell
    1120             :                         // find the parent cell for the current cell at hand
    1121           0 :                         transposeTableMap::iterator it = mergedCellMap.find(transposedIndexofCell);
    1122           0 :                         if(it != mergedCellMap.end())
    1123             :                         {
    1124           0 :                             sal_Int32 transposeIndexOfParent = it->second.first;
    1125           0 :                             Reference< XMergeableCell > parentCell = it->second.second;
    1126             :                             // finding the row and column index for the parent cell from transposed index
    1127           0 :                             sal_Int32 parentColumnIndex = transposeIndexOfParent % nColumnCount;
    1128           0 :                             sal_Int32 parentRowIndex = transposeIndexOfParent / nColumnCount;
    1129           0 :                             if(nColumn == parentColumnIndex)
    1130             :                             {
    1131             :                                 // the cell is vertical merge and it might have gridspan
    1132           0 :                                 if(parentCell->getColumnSpan() > 1)
    1133             :                                 {
    1134             :                                     // vMerge and has gridSpan
    1135             :                                     mpFS->startElementNS( XML_a, XML_tc,
    1136             :                                                           XML_vMerge, I32S(1),
    1137           0 :                                                           XML_gridSpan, I32S(xCell->getColumnSpan()),
    1138           0 :                                                           FSEND );
    1139             :                                 }
    1140             :                                 else
    1141             :                                 {
    1142             :                                     // only vMerge
    1143             :                                     mpFS->startElementNS( XML_a, XML_tc,
    1144           0 :                                                           XML_vMerge, I32S(1), FSEND );
    1145             :                                 }
    1146             :                             }
    1147           0 :                             else if(nRow == parentRowIndex)
    1148             :                             {
    1149             :                                 // the cell is horizontal merge and it might have rowspan
    1150           0 :                                 if(parentCell->getRowSpan() > 1)
    1151             :                                 {
    1152             :                                     // hMerge and has rowspan
    1153             :                                     mpFS->startElementNS( XML_a, XML_tc,
    1154             :                                                           XML_hMerge, I32S(1),
    1155           0 :                                                           XML_rowSpan, I32S(xCell->getRowSpan()),
    1156           0 :                                                           FSEND );
    1157             :                                 }
    1158             :                                 else
    1159             :                                 {
    1160             :                                     // only hMerge
    1161             :                                     mpFS->startElementNS( XML_a, XML_tc,
    1162           0 :                                                           XML_hMerge, I32S(1), FSEND );
    1163             :                                 }
    1164             :                             }
    1165             :                             else
    1166             :                             {
    1167             :                                 // has hMerge and vMerge
    1168             :                                 mpFS->startElementNS( XML_a, XML_tc,
    1169             :                                                       XML_vMerge, I32S(1),
    1170             :                                                       XML_hMerge, I32S(1),
    1171           0 :                                                       FSEND );
    1172           0 :                             }
    1173             :                         }
    1174             :                         else
    1175           0 :                             bCellOpened = false;
    1176             :                     }
    1177             :                 }
    1178             : 
    1179          12 :                 if (bCellOpened)
    1180             :                 {
    1181          12 :                     WriteTextBox( xCell, XML_a );
    1182             : 
    1183          12 :                     Reference< XPropertySet > xCellPropSet(xCell, UNO_QUERY_THROW);
    1184          12 :                     WriteTableCellProperties(xCellPropSet);
    1185             : 
    1186          12 :                     mpFS->endElementNS( XML_a, XML_tc );
    1187             :                 }
    1188          12 :             }
    1189             : 
    1190           6 :             mpFS->endElementNS( XML_a, XML_tr );
    1191           6 :         }
    1192             : 
    1193           8 :         mpFS->endElementNS( XML_a, XML_tbl );
    1194             :     }
    1195             : 
    1196           4 :     mpFS->endElementNS( XML_a, XML_graphicData );
    1197           8 :     mpFS->endElementNS( XML_a, XML_graphic );
    1198           4 : }
    1199             : 
    1200          12 : void ShapeExport::WriteTableCellProperties(Reference< XPropertySet> xCellPropSet)
    1201             : {
    1202          12 :     sal_Int32 nLeftMargin(0), nRightMargin(0);
    1203             : 
    1204          12 :     Any aLeftMargin = xCellPropSet->getPropertyValue("TextLeftDistance");
    1205          12 :     aLeftMargin >>= nLeftMargin;
    1206             : 
    1207          24 :     Any aRightMargin = xCellPropSet->getPropertyValue("TextRightDistance");
    1208          12 :     aRightMargin >>= nRightMargin;
    1209             : 
    1210             :     mpFS->startElementNS( XML_a, XML_tcPr,
    1211          36 :     XML_marL, nLeftMargin > 0 ? I32S( oox::drawingml::convertHmmToEmu( nLeftMargin ) ) : NULL,
    1212          48 :     XML_marR, nRightMargin > 0 ? I32S( oox::drawingml::convertHmmToEmu( nRightMargin ) ): NULL,
    1213          48 :     FSEND );
    1214             : 
    1215             :     // Write background fill for table cell.
    1216             :     // TODO
    1217             :     // tcW : Table cell width
    1218          12 :     WriteTableCellBorders(xCellPropSet);
    1219          12 :     DrawingML::WriteFill(xCellPropSet);
    1220          24 :     mpFS->endElementNS( XML_a, XML_tcPr );
    1221          12 : }
    1222             : 
    1223          12 : void ShapeExport::WriteTableCellBorders(Reference< XPropertySet> xCellPropSet)
    1224             : {
    1225          12 :     BorderLine2 aBorderLine;
    1226             : 
    1227             : // lnL - Left Border Line Properties of table cell
    1228          12 :     xCellPropSet->getPropertyValue("LeftBorder") >>= aBorderLine;
    1229          12 :     sal_Int32 nLeftBorder = aBorderLine.LineWidth;
    1230          12 :     util::Color aLeftBorderColor = aBorderLine.Color;
    1231             : 
    1232             : // While importing the table cell border line width, it converts EMU->Hmm then divided result by 2.
    1233             : // To get original value of LineWidth need to multiple by 2.
    1234          12 :     nLeftBorder = nLeftBorder*2;
    1235          12 :     nLeftBorder = oox::drawingml::convertHmmToEmu( nLeftBorder );
    1236             : 
    1237          12 :     if(nLeftBorder > 0)
    1238             :     {
    1239           8 :         mpFS->startElementNS( XML_a, XML_lnL, XML_w, I32S(nLeftBorder), FSEND );
    1240           8 :         DrawingML::WriteSolidFill(aLeftBorderColor);
    1241           8 :         mpFS->endElementNS( XML_a, XML_lnL );
    1242             :     }
    1243             : 
    1244             : // lnR - Right Border Line Properties of table cell
    1245          12 :     xCellPropSet->getPropertyValue("RightBorder") >>= aBorderLine;
    1246          12 :     sal_Int32 nRightBorder = aBorderLine.LineWidth;
    1247          12 :     util::Color aRightBorderColor = aBorderLine.Color;
    1248          12 :     nRightBorder = nRightBorder * 2 ;
    1249          12 :     nRightBorder = oox::drawingml::convertHmmToEmu( nRightBorder );
    1250             : 
    1251          12 :     if(nRightBorder > 0)
    1252             :     {
    1253           8 :         mpFS->startElementNS( XML_a, XML_lnR, XML_w, I32S(nRightBorder), FSEND);
    1254           8 :         DrawingML::WriteSolidFill(aRightBorderColor);
    1255           8 :         mpFS->endElementNS( XML_a, XML_lnR);
    1256             :     }
    1257             : 
    1258             : // lnT - Top Border Line Properties of table cell
    1259          12 :     xCellPropSet->getPropertyValue("TopBorder") >>= aBorderLine;
    1260          12 :     sal_Int32 nTopBorder = aBorderLine.LineWidth;
    1261          12 :     util::Color aTopBorderColor = aBorderLine.Color;
    1262          12 :     nTopBorder = nTopBorder * 2;
    1263          12 :     nTopBorder = oox::drawingml::convertHmmToEmu( nTopBorder );
    1264             : 
    1265          12 :     if(nTopBorder > 0)
    1266             :     {
    1267           8 :         mpFS->startElementNS( XML_a, XML_lnT, XML_w, I32S(nTopBorder), FSEND);
    1268           8 :         DrawingML::WriteSolidFill(aTopBorderColor);
    1269           8 :         mpFS->endElementNS( XML_a, XML_lnT);
    1270             :     }
    1271             : 
    1272             : // lnB - Bottom Border Line Properties of table cell
    1273          12 :     xCellPropSet->getPropertyValue("BottomBorder") >>= aBorderLine;
    1274          12 :     sal_Int32 nBottomBorder = aBorderLine.LineWidth;
    1275          12 :     util::Color aBottomBorderColor = aBorderLine.Color;
    1276          12 :     nBottomBorder = nBottomBorder * 2;
    1277          12 :     nBottomBorder = oox::drawingml::convertHmmToEmu( nBottomBorder );
    1278             : 
    1279          12 :     if(nBottomBorder > 0)
    1280             :     {
    1281           8 :         mpFS->startElementNS( XML_a, XML_lnB, XML_w, I32S(nBottomBorder), FSEND);
    1282           8 :         DrawingML::WriteSolidFill(aBottomBorderColor);
    1283           8 :         mpFS->endElementNS( XML_a, XML_lnB);
    1284             :     }
    1285          12 : }
    1286             : 
    1287           4 : ShapeExport& ShapeExport::WriteTableShape( Reference< XShape > xShape )
    1288             : {
    1289           4 :     FSHelperPtr pFS = GetFS();
    1290             : 
    1291             :     OSL_TRACE("write table shape");
    1292             : 
    1293           4 :     pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
    1294             : 
    1295           4 :     pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
    1296             : 
    1297             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
    1298             :                           XML_id,     I32S( GetNewShapeID( xShape ) ),
    1299           8 :                           XML_name,   IDS(Table),
    1300           4 :                           FSEND );
    1301             : 
    1302             :     pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
    1303           4 :                           FSEND );
    1304             : 
    1305           4 :     if( GetDocumentType() == DOCUMENT_PPTX )
    1306             :         pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
    1307           4 :                           FSEND );
    1308           4 :     pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
    1309             : 
    1310           4 :     WriteShapeTransformation( xShape, mnXmlNamespace, false);
    1311           4 :     WriteTable( xShape );
    1312             : 
    1313           4 :     pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
    1314             : 
    1315           4 :     return *this;
    1316             : }
    1317             : 
    1318         104 : ShapeExport& ShapeExport::WriteTextShape( Reference< XShape > xShape )
    1319             : {
    1320         104 :     FSHelperPtr pFS = GetFS();
    1321             : 
    1322         104 :     pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
    1323             : 
    1324             :     // non visual shape properties
    1325         104 :     if (GetDocumentType() != DOCUMENT_DOCX)
    1326             :     {
    1327          14 :         pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
    1328          14 :         WriteNonVisualDrawingProperties( xShape, IDS( TextShape ) );
    1329             :     }
    1330         104 :     pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, XML_txBox, "1", FSEND );
    1331         104 :     if (GetDocumentType() != DOCUMENT_DOCX)
    1332             :     {
    1333          14 :         WriteNonVisualProperties( xShape );
    1334          14 :         pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
    1335             :     }
    1336             : 
    1337             :     // visual shape properties
    1338         104 :     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
    1339         104 :     WriteShapeTransformation( xShape, XML_a, false, false, false);
    1340         104 :     WritePresetShape( "rect" );
    1341         208 :     uno::Reference<beans::XPropertySet> xPropertySet(xShape, UNO_QUERY);
    1342         104 :     WriteBlipOrNormalFill(xPropertySet, "GraphicURL");
    1343         104 :     WriteOutline(xPropertySet);
    1344         104 :     pFS->endElementNS( mnXmlNamespace, XML_spPr );
    1345             : 
    1346         104 :     WriteTextBox( xShape, mnXmlNamespace );
    1347             : 
    1348         104 :     pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
    1349             : 
    1350         208 :     return *this;
    1351             : }
    1352             : 
    1353           2 : ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
    1354             : {
    1355           2 :     Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
    1356           2 :     if( xPropSet.is() ) {
    1357           2 :         if( GetProperty( xPropSet, "Model" ) )
    1358             :         {
    1359           2 :             Reference< XChartDocument > xChartDoc;
    1360           2 :             mAny >>= xChartDoc;
    1361           2 :             if( xChartDoc.is() )
    1362             :             {
    1363             :                 //export the chart
    1364           0 :                 Reference< XModel > xModel( xChartDoc, UNO_QUERY );
    1365           0 :                 ChartExport aChartExport( mnXmlNamespace, GetFS(), xModel, GetFB(), GetDocumentType() );
    1366             :                 static sal_Int32 nChartCount = 0;
    1367           0 :                 aChartExport.WriteChartObj( xShape, ++nChartCount );
    1368             :             }
    1369             :             else
    1370             :             {
    1371           2 :                 const bool bSpreadSheet = Reference< XSpreadsheetDocument >( mAny, UNO_QUERY ).is();
    1372           2 :                 const bool bTextDocument = Reference< css::text::XTextDocument >( mAny, UNO_QUERY ).is();
    1373           2 :                 if( ( bSpreadSheet || bTextDocument ) && mpFB)
    1374             :                 {
    1375           2 :                     Reference< XComponent > xDocument( mAny, UNO_QUERY );
    1376           2 :                     if( xDocument.is() )
    1377             :                     {
    1378           2 :                         Reference< XOutputStream > xOutStream;
    1379           2 :                         if( bSpreadSheet )
    1380             :                         {
    1381           0 :                             xOutStream = mpFB->openFragmentStream( OUStringBuffer()
    1382           0 :                                                                    .appendAscii( GetComponentDir() )
    1383           0 :                                                                    .appendAscii( "/embeddings/spreadsheet" )
    1384           0 :                                                                    .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter) )
    1385           0 :                                                                    .appendAscii( ".xlsx" )
    1386             :                                                                    .makeStringAndClear(),
    1387           0 :                                                                    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
    1388             :                         }
    1389             :                         else
    1390             :                         {
    1391           8 :                             xOutStream = mpFB->openFragmentStream( OUStringBuffer()
    1392           4 :                                                                    .appendAscii( GetComponentDir() )
    1393           2 :                                                                    .appendAscii( "/embeddings/textdocument" )
    1394           4 :                                                                    .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter) )
    1395           2 :                                                                    .appendAscii( ".docx" )
    1396             :                                                                    .makeStringAndClear(),
    1397           2 :                                                                    "application/vnd.openxmlformats-officedocument.wordprocessingml.document" );
    1398             :                         }
    1399             : 
    1400             :                         // export the embedded document
    1401           4 :                         Sequence< PropertyValue > rMedia(1);
    1402             : 
    1403           2 :                         rMedia[0].Name = utl::MediaDescriptor::PROP_STREAMFOROUTPUT();
    1404           2 :                         rMedia[0].Value <<= xOutStream;
    1405             : 
    1406           4 :                         Reference< XExporter > xExporter;
    1407           2 :                         if( bSpreadSheet )
    1408             :                         {
    1409             :                             xExporter.set(
    1410           0 :                                 mpFB->getComponentContext()->getServiceManager()->
    1411             :                                     createInstanceWithContext(
    1412             :                                         "com.sun.star.comp.oox.xls.ExcelFilter",
    1413           0 :                                         mpFB->getComponentContext() ),
    1414           0 :                                 UNO_QUERY_THROW );
    1415             :                         }
    1416             :                         else
    1417             :                         {
    1418             :                             xExporter.set(
    1419           4 :                                 mpFB->getComponentContext()->getServiceManager()->
    1420             :                                     createInstanceWithContext(
    1421             :                                         "com.sun.star.comp.Writer.WriterFilter",
    1422           2 :                                         mpFB->getComponentContext() ),
    1423           2 :                                 UNO_QUERY_THROW );
    1424             : 
    1425             :                         }
    1426           2 :                         xExporter->setSourceDocument( xDocument );
    1427           4 :                         Reference< XFilter >( xExporter, UNO_QUERY_THROW )->
    1428           2 :                             filter( rMedia );
    1429             : 
    1430           2 :                         xOutStream->closeOutput();
    1431             : 
    1432           4 :                         OUString sRelId;
    1433           2 :                         if( bSpreadSheet )
    1434             :                         {
    1435           0 :                             sRelId = mpFB->addRelation( mpFS->getOutputStream(),
    1436             :                                                         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
    1437             :                                                         OUStringBuffer()
    1438           0 :                                                         .appendAscii( GetRelationCompPrefix() )
    1439           0 :                                                         .appendAscii( "embeddings/spreadsheet" )
    1440           0 :                                                         .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter++) )
    1441           0 :                                                         .appendAscii( ".xlsx" )
    1442           0 :                                                         .makeStringAndClear() );
    1443             :                         }
    1444             :                         else
    1445             :                         {
    1446           4 :                             sRelId = mpFB->addRelation( mpFS->getOutputStream(),
    1447             :                                                         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
    1448             :                                                         OUStringBuffer()
    1449           4 :                                                         .appendAscii( GetRelationCompPrefix() )
    1450           2 :                                                         .appendAscii( "embeddings/textdocument" )
    1451           4 :                                                         .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter++) )
    1452           2 :                                                         .appendAscii( ".docx" )
    1453           2 :                                                         .makeStringAndClear() );
    1454             :                         }
    1455             : 
    1456           2 :                         mpFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
    1457             : 
    1458           2 :                         mpFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
    1459             : 
    1460             :                         mpFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
    1461             :                                                XML_id,     I32S( GetNewShapeID( xShape ) ),
    1462           4 :                                                XML_name,   IDS(Object),
    1463           2 :                                                FSEND );
    1464             : 
    1465             :                         mpFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
    1466           2 :                                                FSEND );
    1467             : 
    1468           2 :                         if( GetDocumentType() == DOCUMENT_PPTX )
    1469             :                             mpFS->singleElementNS( mnXmlNamespace, XML_nvPr,
    1470           2 :                                                    FSEND );
    1471           2 :                         mpFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
    1472             : 
    1473           2 :                         WriteShapeTransformation( xShape, mnXmlNamespace );
    1474             : 
    1475           2 :                         mpFS->startElementNS( XML_a, XML_graphic, FSEND );
    1476             :                         mpFS->startElementNS( XML_a, XML_graphicData,
    1477             :                                               XML_uri, "http://schemas.openxmlformats.org/presentationml/2006/ole",
    1478           2 :                                               FSEND );
    1479           2 :                         if( bSpreadSheet )
    1480             :                         {
    1481             :                             mpFS->startElementNS( mnXmlNamespace, XML_oleObj,
    1482             :                                               XML_name, "Spreadsheet",
    1483             :                                               FSNS(XML_r, XML_id), USS( sRelId ),
    1484           0 :                                               FSEND );
    1485             :                         }
    1486             :                         else
    1487             :                         {
    1488             :                             mpFS->startElementNS( mnXmlNamespace, XML_oleObj,
    1489             :                                               XML_name, "Document",
    1490             :                                               FSNS(XML_r, XML_id), USS( sRelId ),
    1491             :                                               // The spec says that this is a required attribute, but PowerPoint can only handle an empty value.
    1492             :                                               XML_spid, "",
    1493           2 :                                               FSEND );
    1494             :                         }
    1495             : 
    1496           2 :                         mpFS->singleElementNS( mnXmlNamespace, XML_embed, FSEND );
    1497             : 
    1498             :                         // pic element
    1499           2 :                         SdrObject* pSdrOLE2( GetSdrObjectFromXShape( xShape ) );
    1500             :                         // The spec doesn't allow <p:pic> here, but PowerPoint requires it.
    1501           2 :                         bool bEcma = mpFB->getVersion() == oox::core::ECMA_DIALECT;
    1502           2 :                         if ( pSdrOLE2 && pSdrOLE2->ISA( SdrOle2Obj ) && bEcma)
    1503             :                         {
    1504           0 :                             const Graphic* pGraphic = static_cast<SdrOle2Obj*>(pSdrOLE2)->GetGraphic();
    1505           0 :                             if ( pGraphic )
    1506           0 :                                 WriteGraphicObjectShapePart( xShape, pGraphic );
    1507             :                         }
    1508             : 
    1509           2 :                         mpFS->endElementNS( mnXmlNamespace, XML_oleObj );
    1510             : 
    1511           2 :                         mpFS->endElementNS( XML_a, XML_graphicData );
    1512           2 :                         mpFS->endElementNS( XML_a, XML_graphic );
    1513             : 
    1514           4 :                         mpFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
    1515           2 :                     }
    1516             :                 }
    1517           2 :             }
    1518             :         }
    1519             :     }
    1520           2 :     return *this;
    1521             : }
    1522             : 
    1523         138 : ShapeExport& ShapeExport::WriteUnknownShape( Reference< XShape > )
    1524             : {
    1525             :     // Override this method to do something useful.
    1526         138 :     return *this;
    1527             : }
    1528             : 
    1529        1170 : size_t ShapeExport::ShapeHash::operator()( const Reference < XShape > rXShape ) const
    1530             : {
    1531        1170 :     return rXShape->getShapeType().hashCode();
    1532             : }
    1533             : 
    1534        1170 : sal_Int32 ShapeExport::GetNewShapeID( const Reference< XShape > rXShape )
    1535             : {
    1536        1170 :     return GetNewShapeID( rXShape, GetFB() );
    1537             : }
    1538             : 
    1539        1170 : sal_Int32 ShapeExport::GetNewShapeID( const Reference< XShape > rXShape, XmlFilterBase* pFB )
    1540             : {
    1541        1170 :     if( !rXShape.is() )
    1542           0 :         return -1;
    1543             : 
    1544        1170 :     sal_Int32 nID = pFB->GetUniqueId();
    1545             : 
    1546        1170 :     (*mpShapeMap)[ rXShape ] = nID;
    1547             : 
    1548        1170 :     return nID;
    1549             : }
    1550             : 
    1551           0 : sal_Int32 ShapeExport::GetShapeID( const Reference< XShape > rXShape )
    1552             : {
    1553           0 :     return GetShapeID( rXShape, mpShapeMap );
    1554             : }
    1555             : 
    1556           0 : sal_Int32 ShapeExport::GetShapeID( const Reference< XShape > rXShape, ShapeHashMap* pShapeMap )
    1557             : {
    1558           0 :     if( !rXShape.is() )
    1559           0 :         return -1;
    1560             : 
    1561           0 :     ShapeHashMap::const_iterator aIter = pShapeMap->find( rXShape );
    1562             : 
    1563           0 :     if( aIter == pShapeMap->end() )
    1564           0 :         return -1;
    1565             : 
    1566           0 :     return aIter->second;
    1567             : }
    1568             : 
    1569         246 : } }
    1570             : 
    1571             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11