diff options
Diffstat (limited to 'xmloff/source/draw/shapeimport.cxx')
-rw-r--r-- | xmloff/source/draw/shapeimport.cxx | 1466 |
1 files changed, 1466 insertions, 0 deletions
diff --git a/xmloff/source/draw/shapeimport.cxx b/xmloff/source/draw/shapeimport.cxx new file mode 100644 index 000000000000..903b7d99809a --- /dev/null +++ b/xmloff/source/draw/shapeimport.cxx @@ -0,0 +1,1466 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include <tools/debug.hxx> + +#include <com/sun/star/text/PositionLayoutDir.hpp> +#include <com/sun/star/chart/XChartDocument.hpp> + +#include "unointerfacetouniqueidentifiermapper.hxx" + +#include <list> + +#ifndef _XMLOFF_SHAPEIMPORT_HXX +#include <xmloff/shapeimport.hxx> +#endif +#include <xmloff/xmltkmap.hxx> +#include "xmlnmspe.hxx" +#include <xmloff/xmltoken.hxx> +#include "ximpstyl.hxx" +#include "ximpshap.hxx" +#include "sdpropls.hxx" +#include <xmloff/xmlprmap.hxx> +#include "ximp3dscene.hxx" +#include "ximp3dobject.hxx" +#include "ximpgrp.hxx" +#include "ximplink.hxx" + +#include <map> +#include <vector> + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +using namespace ::std; +using namespace ::com::sun::star; +using namespace ::xmloff::token; + +////////////////////////////////////////////////////////////////////////////// + +struct ltint32 +{ + bool operator()(const sal_Int32 p, sal_Int32 q) const + { + return p < q; + } +}; + +typedef std::map<sal_Int32,com::sun::star::uno::Reference< com::sun::star::drawing::XShape >,ltint32> IdShapeMap; + +struct ConnectionHint +{ + com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxConnector; + sal_Bool bStart; + OUString aDestShapeId; + sal_Int32 nDestGlueId; +}; + +struct XShapeCompareHelper +{ + bool operator()(com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x1, + com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x2 ) const + { + return x1.get() < x2.get(); + } +}; + +/** this map store all glue point id mappings for shapes that had user defined glue points. This + is needed because on insertion the glue points will get a new and unique id */ +typedef std::map<sal_Int32,sal_Int32,ltint32> GluePointIdMap; +typedef std::map< com::sun::star::uno::Reference < com::sun::star::drawing::XShape >, GluePointIdMap, XShapeCompareHelper > ShapeGluePointsMap; + +/** this struct is created for each startPage() call and stores information that is needed during + import of shapes for one page. Since pages could be nested ( notes pages inside impress ) there + is a pointer so one can build up a stack of this structs */ +struct XMLShapeImportPageContextImpl +{ + ShapeGluePointsMap maShapeGluePointsMap; + + uno::Reference < drawing::XShapes > mxShapes; + + struct XMLShapeImportPageContextImpl* mpNext; +}; + +/** this class is to enable adding members to the XMLShapeImportHelper without getting incompatible */ +struct XMLShapeImportHelperImpl +{ + // context for sorting shapes + ShapeSortContext* mpSortContext; + + IdShapeMap maShapeIds; + + std::vector<ConnectionHint> maConnections; + + // #88546# possibility to swich progress bar handling on/off + sal_Bool mbHandleProgressBar; + + // stores the capability of the current model to create presentation shapes + sal_Bool mbIsPresentationShapesSupported; +}; + +////////////////////////////////////////////////////////////////////////////// + +XMLShapeImportHelper::XMLShapeImportHelper( + SvXMLImport& rImporter, + const uno::Reference< frame::XModel>& rModel, + SvXMLImportPropertyMapper *pExtMapper ) +: mpPageContext(NULL), + mxModel(rModel), + + mpPropertySetMapper(0L), + mpPresPagePropsMapper(0L), + mpStylesContext(0L), + mpAutoStylesContext(0L), + mpGroupShapeElemTokenMap(0L), + mpFrameShapeElemTokenMap(0L), + mp3DSceneShapeElemTokenMap(0L), + mp3DObjectAttrTokenMap(0L), + mp3DPolygonBasedAttrTokenMap(0L), + mp3DCubeObjectAttrTokenMap(0L), + mp3DSphereObjectAttrTokenMap(0L), + mp3DSceneShapeAttrTokenMap(0L), + mp3DLightAttrTokenMap(0L), + mpPathShapeAttrTokenMap(0L), + mpPolygonShapeAttrTokenMap(0L), + msStartShape(RTL_CONSTASCII_USTRINGPARAM("StartShape")), + msEndShape(RTL_CONSTASCII_USTRINGPARAM("EndShape")), + msStartGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("StartGluePointIndex")), + msEndGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("EndGluePointIndex")), + + mrImporter( rImporter ) +{ + mpImpl = new XMLShapeImportHelperImpl(); + mpImpl->mpSortContext = 0; + + // #88546# init to FALSE + mpImpl->mbHandleProgressBar = sal_False; + + mpSdPropHdlFactory = new XMLSdPropHdlFactory( rModel, rImporter ); + + // set lock to avoid deletion + mpSdPropHdlFactory->acquire(); + + // construct PropertySetMapper + UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper(mpSdPropHdlFactory); + mpPropertySetMapper = new SvXMLImportPropertyMapper( xMapper, rImporter ); + // set lock to avoid deletion + mpPropertySetMapper->acquire(); + + if( pExtMapper ) + { + UniReference < SvXMLImportPropertyMapper > xExtMapper( pExtMapper ); + mpPropertySetMapper->ChainImportMapper( xExtMapper ); + } + + // chain text attributes + mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImporter)); + mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaDefaultExtPropMapper(rImporter)); + +/* + // chain form attributes + const UniReference< SvXMLImportPropertyMapper> xFormMapper( rImporter.GetFormImport()->getStylePropertyMapper().getBodyPtr() ); + mpPropertySetMapper->ChainImportMapper(xFormMapper); +*/ + + // construct PresPagePropsMapper + xMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLSDPresPageProps, mpSdPropHdlFactory); + mpPresPagePropsMapper = new SvXMLImportPropertyMapper( xMapper, rImporter ); + if(mpPresPagePropsMapper) + { + // set lock to avoid deletion + mpPresPagePropsMapper->acquire(); + } + + uno::Reference< lang::XServiceInfo > xInfo( rImporter.GetModel(), uno::UNO_QUERY ); + const OUString aSName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument") ); + mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService( aSName ); +} + +////////////////////////////////////////////////////////////////////////////// + +XMLShapeImportHelper::~XMLShapeImportHelper() +{ + DBG_ASSERT( mpImpl->maConnections.empty(), "XMLShapeImportHelper::restoreConnections() was not called!" ); + + // cleanup factory, decrease refcount. Should lead to destruction. + if(mpSdPropHdlFactory) + { + mpSdPropHdlFactory->release(); + mpSdPropHdlFactory = 0L; + } + + // cleanup mapper, decrease refcount. Should lead to destruction. + if(mpPropertySetMapper) + { + mpPropertySetMapper->release(); + mpPropertySetMapper = 0L; + } + + // cleanup presPage mapper, decrease refcount. Should lead to destruction. + if(mpPresPagePropsMapper) + { + mpPresPagePropsMapper->release(); + mpPresPagePropsMapper = 0L; + } + + if(mpGroupShapeElemTokenMap) delete mpGroupShapeElemTokenMap; + if(mpFrameShapeElemTokenMap) delete mpFrameShapeElemTokenMap; +/* + if(mpShapeAttrTokenMap) delete mpShapeAttrTokenMap; + if(mpRectShapeAttrTokenMap) delete mpRectShapeAttrTokenMap; + if(mpLineShapeAttrTokenMap) delete mpLineShapeAttrTokenMap; + if(mpEllipseShapeAttrTokenMap) delete mpEllipseShapeAttrTokenMap; + if(mpTextBoxShapeAttrTokenMap) delete mpTextBoxShapeAttrTokenMap; + if(mpControlShapeAttrTokenMap) delete mpControlShapeAttrTokenMap; + if(mpPageShapeAttrTokenMap) delete mpPageShapeAttrTokenMap; + if(mpGraphicObjectShapeAttrTokenMap) delete mpGraphicObjectShapeAttrTokenMap; +*/ + if(mpPolygonShapeAttrTokenMap) delete mpPolygonShapeAttrTokenMap; + if(mpPathShapeAttrTokenMap) delete mpPathShapeAttrTokenMap; + if(mp3DSceneShapeElemTokenMap) delete mp3DSceneShapeElemTokenMap; + if(mp3DObjectAttrTokenMap) delete mp3DObjectAttrTokenMap; + if(mp3DPolygonBasedAttrTokenMap) delete mp3DPolygonBasedAttrTokenMap; + if(mp3DCubeObjectAttrTokenMap) delete mp3DCubeObjectAttrTokenMap; + if(mp3DSphereObjectAttrTokenMap) delete mp3DSphereObjectAttrTokenMap; + if(mp3DSceneShapeAttrTokenMap) delete mp3DSceneShapeAttrTokenMap; + if(mp3DLightAttrTokenMap) delete mp3DLightAttrTokenMap; + + // Styles or AutoStyles context? + if(mpStylesContext) + { + mpStylesContext->Clear(); + mpStylesContext->ReleaseRef(); + } + + if(mpAutoStylesContext) + { + mpAutoStylesContext->Clear(); + mpAutoStylesContext->ReleaseRef(); + } + + delete mpImpl; +} + +////////////////////////////////////////////////////////////////////////////// + + + +const SvXMLTokenMap& XMLShapeImportHelper::GetGroupShapeElemTokenMap() +{ + if(!mpGroupShapeElemTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aGroupShapeElemTokenMap[] = +{ + { XML_NAMESPACE_DRAW, XML_G, XML_TOK_GROUP_GROUP }, + { XML_NAMESPACE_DRAW, XML_RECT, XML_TOK_GROUP_RECT }, + { XML_NAMESPACE_DRAW, XML_LINE, XML_TOK_GROUP_LINE }, + { XML_NAMESPACE_DRAW, XML_CIRCLE, XML_TOK_GROUP_CIRCLE }, + { XML_NAMESPACE_DRAW, XML_ELLIPSE, XML_TOK_GROUP_ELLIPSE }, + { XML_NAMESPACE_DRAW, XML_POLYGON, XML_TOK_GROUP_POLYGON }, + { XML_NAMESPACE_DRAW, XML_POLYLINE, XML_TOK_GROUP_POLYLINE }, + { XML_NAMESPACE_DRAW, XML_PATH, XML_TOK_GROUP_PATH }, + + { XML_NAMESPACE_DRAW, XML_CONTROL, XML_TOK_GROUP_CONTROL }, + { XML_NAMESPACE_DRAW, XML_CONNECTOR, XML_TOK_GROUP_CONNECTOR }, + { XML_NAMESPACE_DRAW, XML_MEASURE, XML_TOK_GROUP_MEASURE }, + { XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, XML_TOK_GROUP_PAGE }, + { XML_NAMESPACE_DRAW, XML_CAPTION, XML_TOK_GROUP_CAPTION }, + + { XML_NAMESPACE_CHART, XML_CHART, XML_TOK_GROUP_CHART }, + { XML_NAMESPACE_DR3D, XML_SCENE, XML_TOK_GROUP_3DSCENE }, + + { XML_NAMESPACE_DRAW, XML_FRAME, XML_TOK_GROUP_FRAME }, + { XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, XML_TOK_GROUP_CUSTOM_SHAPE }, + + { XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, XML_TOK_GROUP_CUSTOM_SHAPE }, + { XML_NAMESPACE_OFFICE, XML_ANNOTATION, XML_TOK_GROUP_ANNOTATION }, + { XML_NAMESPACE_DRAW, XML_A, XML_TOK_GROUP_A }, + + XML_TOKEN_MAP_END +}; + + mpGroupShapeElemTokenMap = new SvXMLTokenMap(aGroupShapeElemTokenMap); + } // if(!mpGroupShapeElemTokenMap) + + return *mpGroupShapeElemTokenMap; +} + +const SvXMLTokenMap& XMLShapeImportHelper::GetFrameShapeElemTokenMap() +{ + if(!mpFrameShapeElemTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aFrameShapeElemTokenMap[] = +{ + { XML_NAMESPACE_DRAW, XML_TEXT_BOX, XML_TOK_FRAME_TEXT_BOX }, + { XML_NAMESPACE_DRAW, XML_IMAGE, XML_TOK_FRAME_IMAGE }, + { XML_NAMESPACE_DRAW, XML_OBJECT, XML_TOK_FRAME_OBJECT }, + { XML_NAMESPACE_DRAW, XML_OBJECT_OLE, XML_TOK_FRAME_OBJECT_OLE }, + { XML_NAMESPACE_DRAW, XML_PLUGIN, XML_TOK_FRAME_PLUGIN }, + { XML_NAMESPACE_DRAW, XML_FLOATING_FRAME, XML_TOK_FRAME_FLOATING_FRAME}, + { XML_NAMESPACE_DRAW, XML_APPLET, XML_TOK_FRAME_APPLET }, + { XML_NAMESPACE_TABLE, XML_TABLE, XML_TOK_FRAME_TABLE }, + XML_TOKEN_MAP_END +}; + + mpFrameShapeElemTokenMap = new SvXMLTokenMap(aFrameShapeElemTokenMap); + } // if(!mpFrameShapeElemTokenMap) + + return *mpFrameShapeElemTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::Get3DSceneShapeElemTokenMap() +{ + if(!mp3DSceneShapeElemTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry a3DSceneShapeElemTokenMap[] = +{ + { XML_NAMESPACE_DR3D, XML_SCENE, XML_TOK_3DSCENE_3DSCENE }, + { XML_NAMESPACE_DR3D, XML_CUBE, XML_TOK_3DSCENE_3DCUBE }, + { XML_NAMESPACE_DR3D, XML_SPHERE, XML_TOK_3DSCENE_3DSPHERE }, + { XML_NAMESPACE_DR3D, XML_ROTATE, XML_TOK_3DSCENE_3DLATHE }, + { XML_NAMESPACE_DR3D, XML_EXTRUDE, XML_TOK_3DSCENE_3DEXTRUDE }, + XML_TOKEN_MAP_END +}; + + mp3DSceneShapeElemTokenMap = new SvXMLTokenMap(a3DSceneShapeElemTokenMap); + } // if(!mp3DSceneShapeElemTokenMap) + + return *mp3DSceneShapeElemTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// +/* + +const SvXMLTokenMap& XMLShapeImportHelper::GetShapeAttrTokenMap() +{ + if(!mpShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_SHAPE_NAME }, + { XML_NAMESPACE_DRAW, XML_STYLE_NAME, XML_TOK_SHAPE_DRAWSTYLE_NAME_GRAPHICS }, + { XML_NAMESPACE_PRESENTATION, XML_CLASS, XML_TOK_SHAPE_PRESENTATION_CLASS }, + { XML_NAMESPACE_PRESENTATION, XML_STYLE_NAME, XML_TOK_SHAPE_DRAWSTYLE_NAME_PRESENTATION }, + { XML_NAMESPACE_SVG, XML_TRANSFORM, XML_TOK_SHAPE_TRANSFORM }, + { XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, XML_TOK_SHAPE_IS_PLACEHOLDER }, + { XML_NAMESPACE_PRESENTATION, XML_USER_TRANSFORMED, XML_TOK_SHAPE_IS_USER_TRANSFORMED }, + XML_TOKEN_MAP_END +}; + + mpShapeAttrTokenMap = new SvXMLTokenMap(aShapeAttrTokenMap); + } + + return *mpShapeAttrTokenMap; +} +*/ +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::Get3DObjectAttrTokenMap() +{ + if(!mp3DObjectAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry a3DObjectAttrTokenMap[] = +{ + { XML_NAMESPACE_DRAW, XML_STYLE_NAME, XML_TOK_3DOBJECT_DRAWSTYLE_NAME }, + { XML_NAMESPACE_DR3D, XML_TRANSFORM, XML_TOK_3DOBJECT_TRANSFORM }, + XML_TOKEN_MAP_END +}; + + mp3DObjectAttrTokenMap = new SvXMLTokenMap(a3DObjectAttrTokenMap); + } // if(!mp3DObjectAttrTokenMap) + + return *mp3DObjectAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::Get3DPolygonBasedAttrTokenMap() +{ + if(!mp3DPolygonBasedAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry a3DPolygonBasedAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_VIEWBOX, XML_TOK_3DPOLYGONBASED_VIEWBOX }, + { XML_NAMESPACE_SVG, XML_D, XML_TOK_3DPOLYGONBASED_D }, + XML_TOKEN_MAP_END +}; + + mp3DPolygonBasedAttrTokenMap = new SvXMLTokenMap(a3DPolygonBasedAttrTokenMap); + } // if(!mp3DPolygonBasedAttrTokenMap) + + return *mp3DPolygonBasedAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::Get3DCubeObjectAttrTokenMap() +{ + if(!mp3DCubeObjectAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry a3DCubeObjectAttrTokenMap[] = +{ + { XML_NAMESPACE_DR3D, XML_MIN_EDGE, XML_TOK_3DCUBEOBJ_MINEDGE }, + { XML_NAMESPACE_DR3D, XML_MAX_EDGE, XML_TOK_3DCUBEOBJ_MAXEDGE }, + XML_TOKEN_MAP_END +}; + + mp3DCubeObjectAttrTokenMap = new SvXMLTokenMap(a3DCubeObjectAttrTokenMap); + } // if(!mp3DCubeObjectAttrTokenMap) + + return *mp3DCubeObjectAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::Get3DSphereObjectAttrTokenMap() +{ + if(!mp3DSphereObjectAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry a3DSphereObjectAttrTokenMap[] = +{ + { XML_NAMESPACE_DR3D, XML_CENTER, XML_TOK_3DSPHEREOBJ_CENTER }, + { XML_NAMESPACE_DR3D, XML_SIZE, XML_TOK_3DSPHEREOBJ_SIZE }, + XML_TOKEN_MAP_END +}; + + mp3DSphereObjectAttrTokenMap = new SvXMLTokenMap(a3DSphereObjectAttrTokenMap); + } // if(!mp3DSphereObjectAttrTokenMap) + + return *mp3DSphereObjectAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// +/* + +const SvXMLTokenMap& XMLShapeImportHelper::GetRectShapeAttrTokenMap() +{ + if(!mpRectShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aRectShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_X, XML_TOK_RECTSHAPE_X }, + { XML_NAMESPACE_SVG, XML_Y, XML_TOK_RECTSHAPE_Y }, + { XML_NAMESPACE_SVG, XML_WIDTH, XML_TOK_RECTSHAPE_WIDTH }, + { XML_NAMESPACE_SVG, XML_HEIGHT, XML_TOK_RECTSHAPE_HEIGHT }, + { XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, XML_TOK_RECTSHAPE_CORNER_RADIUS }, + XML_TOKEN_MAP_END +}; + + mpRectShapeAttrTokenMap = new SvXMLTokenMap(aRectShapeAttrTokenMap); + } + + return *mpRectShapeAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::GetLineShapeAttrTokenMap() +{ + if(!mpLineShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aLineShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_X1, XML_TOK_LINESHAPE_X1 }, + { XML_NAMESPACE_SVG, XML_Y1, XML_TOK_LINESHAPE_Y1 }, + { XML_NAMESPACE_SVG, XML_X2, XML_TOK_LINESHAPE_X2 }, + { XML_NAMESPACE_SVG, XML_Y2, XML_TOK_LINESHAPE_Y2 }, + XML_TOKEN_MAP_END +}; + + mpLineShapeAttrTokenMap = new SvXMLTokenMap(aLineShapeAttrTokenMap); + } + + return *mpLineShapeAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::GetEllipseShapeAttrTokenMap() +{ + if(!mpEllipseShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aEllipseShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_RX, XML_TOK_ELLIPSESHAPE_RX }, + { XML_NAMESPACE_SVG, XML_RY, XML_TOK_ELLIPSESHAPE_RY }, + { XML_NAMESPACE_SVG, XML_CX, XML_TOK_ELLIPSESHAPE_CX }, + { XML_NAMESPACE_SVG, XML_CY, XML_TOK_ELLIPSESHAPE_CY }, + { XML_NAMESPACE_SVG, XML_R, XML_TOK_ELLIPSESHAPE_R }, + XML_TOKEN_MAP_END +}; + + mpEllipseShapeAttrTokenMap = new SvXMLTokenMap(aEllipseShapeAttrTokenMap); + } + + return *mpEllipseShapeAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// +*/ + +const SvXMLTokenMap& XMLShapeImportHelper::GetPolygonShapeAttrTokenMap() +{ + if(!mpPolygonShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aPolygonShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_VIEWBOX, XML_TOK_POLYGONSHAPE_VIEWBOX }, + { XML_NAMESPACE_DRAW, XML_POINTS, XML_TOK_POLYGONSHAPE_POINTS }, + XML_TOKEN_MAP_END +}; + + mpPolygonShapeAttrTokenMap = new SvXMLTokenMap(aPolygonShapeAttrTokenMap); + } // if(!mpPolygonShapeAttrTokenMap) + + return *mpPolygonShapeAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::GetPathShapeAttrTokenMap() +{ + if(!mpPathShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aPathShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_VIEWBOX, XML_TOK_PATHSHAPE_VIEWBOX }, + { XML_NAMESPACE_SVG, XML_D, XML_TOK_PATHSHAPE_D }, + XML_TOKEN_MAP_END +}; + + mpPathShapeAttrTokenMap = new SvXMLTokenMap(aPathShapeAttrTokenMap); + } // if(!mpPathShapeAttrTokenMap) + + return *mpPathShapeAttrTokenMap; +} +/* +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::GetTextBoxShapeAttrTokenMap() +{ + if(!mpTextBoxShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aTextBoxShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_X, XML_TOK_TEXTBOXSHAPE_X }, + { XML_NAMESPACE_SVG, XML_Y, XML_TOK_TEXTBOXSHAPE_Y }, + { XML_NAMESPACE_SVG, XML_WIDTH, XML_TOK_TEXTBOXSHAPE_WIDTH }, + { XML_NAMESPACE_SVG, XML_HEIGHT, XML_TOK_TEXTBOXSHAPE_HEIGHT }, + XML_TOKEN_MAP_END +}; + + mpTextBoxShapeAttrTokenMap = new SvXMLTokenMap(aTextBoxShapeAttrTokenMap); + } + + return *mpTextBoxShapeAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::GetControlShapeAttrTokenMap() +{ + if(!mpControlShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aControlShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_X, XML_TOK_CONTROLSHAPE_X }, + { XML_NAMESPACE_SVG, XML_Y, XML_TOK_CONTROLSHAPE_Y }, + { XML_NAMESPACE_SVG, XML_WIDTH, XML_TOK_CONTROLSHAPE_WIDTH }, + { XML_NAMESPACE_SVG, XML_HEIGHT, XML_TOK_CONTROLSHAPE_HEIGHT }, + XML_TOKEN_MAP_END +}; + + mpControlShapeAttrTokenMap = new SvXMLTokenMap(aControlShapeAttrTokenMap); + } + + return *mpControlShapeAttrTokenMap; +} +*/ +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::Get3DSceneShapeAttrTokenMap() +{ + if(!mp3DSceneShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry a3DSceneShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_DR3D, XML_TRANSFORM, XML_TOK_3DSCENESHAPE_TRANSFORM }, + { XML_NAMESPACE_DR3D, XML_VRP, XML_TOK_3DSCENESHAPE_VRP }, + { XML_NAMESPACE_DR3D, XML_VPN, XML_TOK_3DSCENESHAPE_VPN }, + { XML_NAMESPACE_DR3D, XML_VUP, XML_TOK_3DSCENESHAPE_VUP }, + { XML_NAMESPACE_DR3D, XML_PROJECTION, XML_TOK_3DSCENESHAPE_PROJECTION }, + { XML_NAMESPACE_DR3D, XML_DISTANCE, XML_TOK_3DSCENESHAPE_DISTANCE }, + { XML_NAMESPACE_DR3D, XML_FOCAL_LENGTH, XML_TOK_3DSCENESHAPE_FOCAL_LENGTH }, + { XML_NAMESPACE_DR3D, XML_SHADOW_SLANT, XML_TOK_3DSCENESHAPE_SHADOW_SLANT }, + { XML_NAMESPACE_DR3D, XML_SHADE_MODE, XML_TOK_3DSCENESHAPE_SHADE_MODE }, + { XML_NAMESPACE_DR3D, XML_AMBIENT_COLOR, XML_TOK_3DSCENESHAPE_AMBIENT_COLOR }, + { XML_NAMESPACE_DR3D, XML_LIGHTING_MODE, XML_TOK_3DSCENESHAPE_LIGHTING_MODE }, + XML_TOKEN_MAP_END +}; + + mp3DSceneShapeAttrTokenMap = new SvXMLTokenMap(a3DSceneShapeAttrTokenMap); + } // if(!mp3DSceneShapeAttrTokenMap) + + return *mp3DSceneShapeAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::Get3DLightAttrTokenMap() +{ + if(!mp3DLightAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry a3DLightAttrTokenMap[] = +{ + { XML_NAMESPACE_DR3D, XML_DIFFUSE_COLOR, XML_TOK_3DLIGHT_DIFFUSE_COLOR }, + { XML_NAMESPACE_DR3D, XML_DIRECTION, XML_TOK_3DLIGHT_DIRECTION }, + { XML_NAMESPACE_DR3D, XML_ENABLED, XML_TOK_3DLIGHT_ENABLED }, + { XML_NAMESPACE_DR3D, XML_SPECULAR, XML_TOK_3DLIGHT_SPECULAR }, + XML_TOKEN_MAP_END +}; + + mp3DLightAttrTokenMap = new SvXMLTokenMap(a3DLightAttrTokenMap); + } // if(!mp3DLightAttrTokenMap) + + return *mp3DLightAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// +/* + +const SvXMLTokenMap& XMLShapeImportHelper::GetPageShapeAttrTokenMap() +{ + if(!mpPageShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aPageShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_X, XML_TOK_PAGESHAPE_X }, + { XML_NAMESPACE_SVG, XML_Y, XML_TOK_PAGESHAPE_Y }, + { XML_NAMESPACE_SVG, XML_WIDTH, XML_TOK_PAGESHAPE_WIDTH }, + { XML_NAMESPACE_SVG, XML_HEIGHT, XML_TOK_PAGESHAPE_HEIGHT }, + XML_TOKEN_MAP_END +}; + + mpPageShapeAttrTokenMap = new SvXMLTokenMap(aPageShapeAttrTokenMap); + } + + return *mpPageShapeAttrTokenMap; +} + +////////////////////////////////////////////////////////////////////////////// + + +const SvXMLTokenMap& XMLShapeImportHelper::GetGraphicObjectShapeAttrTokenMap() +{ + if(!mpGraphicObjectShapeAttrTokenMap) + { + static __FAR_DATA SvXMLTokenMapEntry aGraphicObjectShapeAttrTokenMap[] = +{ + { XML_NAMESPACE_SVG, XML_X, XML_TOK_GOSHAPE_X }, + { XML_NAMESPACE_SVG, XML_Y, XML_TOK_GOSHAPE_Y }, + { XML_NAMESPACE_SVG, XML_WIDTH, XML_TOK_GOSHAPE_WIDTH }, + { XML_NAMESPACE_SVG, XML_HEIGHT, XML_TOK_GOSHAPE_HEIGHT }, + { XML_NAMESPACE_XLINK, XML_HREF, XML_TOK_GOSHAPE_URL }, + XML_TOKEN_MAP_END +}; + + mpGraphicObjectShapeAttrTokenMap = new SvXMLTokenMap(aGraphicObjectShapeAttrTokenMap); + } + + return *mpGraphicObjectShapeAttrTokenMap; +} +*/ +////////////////////////////////////////////////////////////////////////////// + +SvXMLShapeContext* XMLShapeImportHelper::Create3DSceneChildContext( + SvXMLImport& rImport, + USHORT p_nPrefix, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList>& xAttrList, + uno::Reference< drawing::XShapes >& rShapes) +{ + SdXMLShapeContext *pContext = 0L; + + if(rShapes.is()) + { + const SvXMLTokenMap& rTokenMap = Get3DSceneShapeElemTokenMap(); + switch(rTokenMap.Get(p_nPrefix, rLocalName)) + { + case XML_TOK_3DSCENE_3DSCENE: + { + // dr3d:3dscene inside dr3d:3dscene context + pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False); + break; + } + case XML_TOK_3DSCENE_3DCUBE: + { + // dr3d:3dcube inside dr3d:3dscene context + pContext = new SdXML3DCubeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False); + break; + } + case XML_TOK_3DSCENE_3DSPHERE: + { + // dr3d:3dsphere inside dr3d:3dscene context + pContext = new SdXML3DSphereObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False); + break; + } + case XML_TOK_3DSCENE_3DLATHE: + { + // dr3d:3dlathe inside dr3d:3dscene context + pContext = new SdXML3DLatheObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False); + break; + } + case XML_TOK_3DSCENE_3DEXTRUDE: + { + // dr3d:3dextrude inside dr3d:3dscene context + pContext = new SdXML3DExtrudeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False); + break; + } + } + } + + // now parse the attribute list and call the child context for each unknown attribute + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for(sal_Int16 a(0); a < nAttrCount; a++) + { + const OUString& rAttrName = xAttrList->getNameByIndex(a); + OUString aLocalName; + sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName); + const OUString aValue( xAttrList->getValueByIndex(a) ); + + pContext->processAttribute( nPrefix, aLocalName, aValue ); + } + + return pContext; +} + +////////////////////////////////////////////////////////////////////////////// + +void XMLShapeImportHelper::SetStylesContext(SvXMLStylesContext* pNew) +{ + mpStylesContext = pNew; + mpStylesContext->AddRef(); +} + +////////////////////////////////////////////////////////////////////////////// + +void XMLShapeImportHelper::SetAutoStylesContext(SvXMLStylesContext* pNew) +{ + mpAutoStylesContext = pNew; + mpAutoStylesContext->AddRef(); +} + +////////////////////////////////////////////////////////////////////////////// + +SvXMLShapeContext* XMLShapeImportHelper::CreateGroupChildContext( + SvXMLImport& rImport, + USHORT p_nPrefix, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList>& xAttrList, + uno::Reference< drawing::XShapes >& rShapes, + sal_Bool bTemporaryShape) +{ + SdXMLShapeContext *pContext = 0L; + + const SvXMLTokenMap& rTokenMap = GetGroupShapeElemTokenMap(); + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + + switch(rTokenMap.Get(p_nPrefix, rLocalName)) + { + case XML_TOK_GROUP_GROUP: + { + // draw:g inside group context (RECURSIVE) + pContext = new SdXMLGroupShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape); + break; + } + case XML_TOK_GROUP_3DSCENE: + { + // dr3d:3dscene inside group context + pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape); + break; + } + case XML_TOK_GROUP_RECT: + { + // draw:rect inside group context + pContext = new SdXMLRectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_LINE: + { + // draw:line inside group context + pContext = new SdXMLLineShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_CIRCLE: + case XML_TOK_GROUP_ELLIPSE: + { + // draw:circle or draw:ellipse inside group context + pContext = new SdXMLEllipseShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_POLYGON: + case XML_TOK_GROUP_POLYLINE: + { + // draw:polygon or draw:polyline inside group context + pContext = new SdXMLPolygonShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, + rTokenMap.Get(p_nPrefix, rLocalName) == XML_TOK_GROUP_POLYGON ? TRUE : FALSE, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_PATH: + { + // draw:path inside group context + pContext = new SdXMLPathShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape); + break; + } + case XML_TOK_GROUP_FRAME: + { + // text:text-box inside group context + pContext = new SdXMLFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_CONTROL: + { + // draw:control inside group context + pContext = new SdXMLControlShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_CONNECTOR: + { + // draw:connector inside group context + pContext = new SdXMLConnectorShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_MEASURE: + { + // draw:measure inside group context + pContext = new SdXMLMeasureShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_PAGE: + { + // draw:page inside group context + pContext = new SdXMLPageShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_CAPTION: + case XML_TOK_GROUP_ANNOTATION: + { + // draw:caption inside group context + pContext = new SdXMLCaptionShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_CHART: + { + // chart:chart inside group context + pContext = new SdXMLChartShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape ); + break; + } + case XML_TOK_GROUP_CUSTOM_SHAPE: + { + // draw:customshape + pContext = new SdXMLCustomShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False ); + break; + } + case XML_TOK_GROUP_A: + { + return new SdXMLShapeLinkContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes ); + } + // add other shapes here... + default: + return new SvXMLShapeContext( rImport, p_nPrefix, rLocalName, bTemporaryShape ); + } + + // now parse the attribute list and call the child context for each unknown attribute + for(sal_Int16 a(0); a < nAttrCount; a++) + { + const OUString& rAttrName = xAttrList->getNameByIndex(a); + OUString aLocalName; + sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName); + const OUString aValue( xAttrList->getValueByIndex(a) ); + + pContext->processAttribute( nPrefix, aLocalName, aValue ); + } + + return pContext; +} + +// This method is called from SdXMLFrameContext to create children of drawe:frame +SvXMLShapeContext* XMLShapeImportHelper::CreateFrameChildContext( + SvXMLImport& rImport, + USHORT p_nPrefix, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList>& rAttrList, + uno::Reference< drawing::XShapes >& rShapes, + const uno::Reference< xml::sax::XAttributeList>& rFrameAttrList) +{ + SdXMLShapeContext *pContext = 0L; + + const SvXMLTokenMap& rTokenMap = GetFrameShapeElemTokenMap(); + + SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList ); + if( rFrameAttrList.is() ) + pAttrList->AppendAttributeList( rFrameAttrList ); + uno::Reference < xml::sax::XAttributeList > xAttrList = pAttrList; + + + switch(rTokenMap.Get(p_nPrefix, rLocalName)) + { + case XML_TOK_FRAME_TEXT_BOX: + { + // text:text-box inside group context + pContext = new SdXMLTextBoxShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False ); + break; + } + case XML_TOK_FRAME_IMAGE: + { + // office:image inside group context + pContext = new SdXMLGraphicObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False ); + break; + } + case XML_TOK_FRAME_OBJECT: + case XML_TOK_FRAME_OBJECT_OLE: + { + // draw:object or draw:object_ole + pContext = new SdXMLObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False ); + break; + } + case XML_TOK_FRAME_TABLE: + { + // draw:object or draw:object_ole + if( rImport.IsTableShapeSupported() ) + pContext = new SdXMLTableShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes ); + break; + + } + case XML_TOK_FRAME_PLUGIN: + { + // draw:plugin + pContext = new SdXMLPluginShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False ); + break; + } + case XML_TOK_FRAME_FLOATING_FRAME: + { + // draw:floating-frame + pContext = new SdXMLFloatingFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False ); + break; + } + case XML_TOK_FRAME_APPLET: + { + // draw:applet + pContext = new SdXMLAppletShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False ); + break; + } + // add other shapes here... + default: + break; + } + + if( pContext ) + { + // now parse the attribute list and call the child context for each unknown attribute + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for(sal_Int16 a(0); a < nAttrCount; a++) + { + const OUString& rAttrName = xAttrList->getNameByIndex(a); + OUString aLocalName; + sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName); + const OUString aValue( xAttrList->getValueByIndex(a) ); + + pContext->processAttribute( nPrefix, aLocalName, aValue ); + } + } + + return pContext; +} + +SvXMLImportContext *XMLShapeImportHelper::CreateFrameChildContext( + SvXMLImportContext *pThisContext, + USHORT nPrefix, + const OUString& rLocalName, + const uno::Reference< xml::sax::XAttributeList>& xAttrList ) +{ + SvXMLImportContext * pContext = NULL; + + SdXMLFrameShapeContext *pFrameContext = PTR_CAST( SdXMLFrameShapeContext, pThisContext ); + if( pFrameContext ) + pContext = pFrameContext->CreateChildContext( nPrefix, rLocalName, xAttrList ); + + return pContext; +} + + +/** this function is called whenever the implementation classes like to add this new + shape to the given XShapes. +*/ +void XMLShapeImportHelper::addShape( uno::Reference< drawing::XShape >& rShape, + const uno::Reference< xml::sax::XAttributeList >&, + uno::Reference< drawing::XShapes >& rShapes) +{ + if( rShape.is() && rShapes.is() ) + { + // add new shape to parent + rShapes->add( rShape ); + } +} + +/** this function is called whenever the implementation classes have finished importing + a shape to the given XShapes. The shape is already inserted into its XShapes and + all properties and styles are set. +*/ +void XMLShapeImportHelper::finishShape( + com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >&, + com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >&) +{ + // --> OD 2004-08-10 #i28749#, #i36248# - set property <PositionLayoutDir> + // to <PositionInHoriL2R>, if it exists and the import states that + // the shape positioning attributes are in horizontal left-to-right + // layout. This is the case for the OpenOffice.org file format. + // This setting is done for Writer documents, because the property + // only exists at service com::sun::star::text::Shape - the Writer + // UNO service for shapes. + // The value indicates that the positioning attributes are given + // in horizontal left-to-right layout. The property is evaluated + // during the first positioning of the shape in order to convert + // the shape position given in the OpenOffice.org file format to + // the one for the OASIS Open Office file format. + uno::Reference< beans::XPropertySet > xPropSet(rShape, uno::UNO_QUERY); + if ( xPropSet.is() ) + { + if ( mrImporter.IsShapePositionInHoriL2R() && + xPropSet->getPropertySetInfo()->hasPropertyByName( + OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir"))) ) + { + uno::Any aPosLayoutDir; + aPosLayoutDir <<= text::PositionLayoutDir::PositionInHoriL2R; + xPropSet->setPropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir")), + aPosLayoutDir ); + } + } + // <-- +} + +// helper functions for z-order sorting +struct ZOrderHint +{ + sal_Int32 nIs; + sal_Int32 nShould; + + int operator<(const ZOrderHint& rComp) const { return nShould < rComp.nShould; } +}; + +class ShapeSortContext +{ +public: + uno::Reference< drawing::XShapes > mxShapes; + list<ZOrderHint> maZOrderList; + list<ZOrderHint> maUnsortedList; + + sal_Int32 mnCurrentZ; + ShapeSortContext* mpParentContext; + const OUString msZOrder; + + ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext = NULL ); + + void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos ); +}; + +ShapeSortContext::ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext ) +: mxShapes( rShapes ), mnCurrentZ( 0 ), mpParentContext( pParentContext ), + msZOrder(RTL_CONSTASCII_USTRINGPARAM("ZOrder")) +{ +} + +void ShapeSortContext::moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos ) +{ + uno::Any aAny( mxShapes->getByIndex( nSourcePos ) ); + uno::Reference< beans::XPropertySet > xPropSet; + aAny >>= xPropSet; + + if( xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName( msZOrder ) ) + { + aAny <<= nDestPos; + xPropSet->setPropertyValue( msZOrder, aAny ); + + list<ZOrderHint>::iterator aIter = maZOrderList.begin(); + list<ZOrderHint>::iterator aEnd = maZOrderList.end(); + + while( aIter != aEnd ) + { + if( (*aIter).nIs < nSourcePos ) + { + DBG_ASSERT( (*aIter).nIs >= nDestPos, "Shape sorting failed" ); + (*aIter).nIs++; + } + aIter++; + } + + aIter = maUnsortedList.begin(); + aEnd = maUnsortedList.end(); + + while( aIter != aEnd ) + { + if( (*aIter).nIs < nSourcePos ) + { + DBG_ASSERT( (*aIter).nIs >= nDestPos, "shape sorting failed" ); + (*aIter).nIs++; + } + aIter++; + } + } +} + +void XMLShapeImportHelper::pushGroupForSorting( uno::Reference< drawing::XShapes >& rShapes ) +{ + mpImpl->mpSortContext = new ShapeSortContext( rShapes, mpImpl->mpSortContext ); +} + +void XMLShapeImportHelper::popGroupAndSort() +{ + DBG_ASSERT( mpImpl->mpSortContext, "No context to sort!" ); + if( mpImpl->mpSortContext == NULL ) + return; + + try + { + list<ZOrderHint>& rZList = mpImpl->mpSortContext->maZOrderList; + list<ZOrderHint>& rUnsortedList = mpImpl->mpSortContext->maUnsortedList; + + // sort shapes + if( !rZList.empty() ) + { + // only do something if we have shapes to sort + + // check if there are more shapes than inserted with ::shapeWithZIndexAdded() + // This can happen if there where already shapes on the page before import + // Since the writer may delete some of this shapes during import, we need + // to do this here and not in our c'tor anymore + + // check if we have more shapes than we know of + sal_Int32 nCount = mpImpl->mpSortContext->mxShapes->getCount(); + + nCount -= rZList.size(); + nCount -= rUnsortedList.size(); + + + if( nCount > 0 ) + { + // first update offsets of added shapes + list<ZOrderHint>::iterator aIter( rZList.begin() ); + while( aIter != rZList.end() ) + (*aIter++).nIs += nCount; + + aIter = rUnsortedList.begin(); + while( aIter != rUnsortedList.end() ) + (*aIter++).nIs += nCount; + + // second add the already existing shapes in the unsorted list + ZOrderHint aNewHint; + + do + { + nCount--; + + aNewHint.nIs = nCount; + aNewHint.nShould = -1; + + rUnsortedList.insert(rUnsortedList.begin(), aNewHint); + } + while( nCount ); + } + + // sort z ordered shapes + rZList.sort(); + + // this is the current index, all shapes before that + // index are finished + sal_Int32 nIndex = 0; + while( !rZList.empty() ) + { + list<ZOrderHint>::iterator aIter( rZList.begin() ); + + while( nIndex < (*aIter).nShould && !rUnsortedList.empty() ) + { + ZOrderHint aGapHint( *rUnsortedList.begin() ); + rUnsortedList.pop_front(); + + mpImpl->mpSortContext->moveShape( aGapHint.nIs, nIndex++ ); + } + + if( (*aIter).nIs != nIndex ) + mpImpl->mpSortContext->moveShape( (*aIter).nIs, nIndex ); + + rZList.pop_front(); + nIndex++; + } + } + } + catch( uno::Exception& ) + { + DBG_ERROR("exception while sorting shapes, sorting failed!"); + } + + // put parent on top and delete current context, were done + ShapeSortContext* pContext = mpImpl->mpSortContext; + mpImpl->mpSortContext = pContext->mpParentContext; + delete pContext; +} + +void XMLShapeImportHelper::shapeWithZIndexAdded( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >&, sal_Int32 nZIndex ) +{ + if( mpImpl->mpSortContext) + { + ZOrderHint aNewHint; + aNewHint.nIs = mpImpl->mpSortContext->mnCurrentZ++; + aNewHint.nShould = nZIndex; + + if( nZIndex == -1 ) + { + // don't care, so add to unsorted list + mpImpl->mpSortContext->maUnsortedList.push_back(aNewHint); + } + else + { + // insert into sort list + mpImpl->mpSortContext->maZOrderList.push_back(aNewHint); + } + } +} + +void XMLShapeImportHelper::addShapeConnection( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rConnectorShape, + sal_Bool bStart, + const rtl::OUString& rDestShapeId, + sal_Int32 nDestGlueId ) +{ + ConnectionHint aHint; + aHint.mxConnector = rConnectorShape; + aHint.bStart = bStart; + aHint.aDestShapeId = rDestShapeId; + aHint.nDestGlueId = nDestGlueId; + + mpImpl->maConnections.push_back( aHint ); +} + +void XMLShapeImportHelper::restoreConnections() +{ + if( !mpImpl->maConnections.empty() ) + { + uno::Any aAny; + + const vector<ConnectionHint>::size_type nCount = mpImpl->maConnections.size(); + for( vector<ConnectionHint>::size_type i = 0; i < nCount; i++ ) + { + ConnectionHint& rHint = mpImpl->maConnections[i]; + uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY ); + if( xConnector.is() ) + { + // #86637# remember line deltas + uno::Any aLine1Delta; + uno::Any aLine2Delta; + uno::Any aLine3Delta; + OUString aStr1(RTL_CONSTASCII_USTRINGPARAM("EdgeLine1Delta")); + OUString aStr2(RTL_CONSTASCII_USTRINGPARAM("EdgeLine2Delta")); + OUString aStr3(RTL_CONSTASCII_USTRINGPARAM("EdgeLine3Delta")); + aLine1Delta = xConnector->getPropertyValue(aStr1); + aLine2Delta = xConnector->getPropertyValue(aStr2); + aLine3Delta = xConnector->getPropertyValue(aStr3); + + // #86637# simply setting these values WILL force the connector to do + // an new layout promptly. So the line delta values have to be rescued + // and restored around connector changes. + uno::Reference< drawing::XShape > xShape( + mrImporter.getInterfaceToIdentifierMapper().getReference( rHint.aDestShapeId ), uno::UNO_QUERY ); + if( xShape.is() ) + { + aAny <<= xShape; + xConnector->setPropertyValue( rHint.bStart ? msStartShape : msEndShape, aAny ); + + sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId : getGluePointId( xShape, rHint.nDestGlueId ); + aAny <<= nGlueId; + xConnector->setPropertyValue( rHint.bStart ? msStartGluePointIndex : msEndGluePointIndex, aAny ); + } + + // #86637# restore line deltas + xConnector->setPropertyValue(aStr1, aLine1Delta ); + xConnector->setPropertyValue(aStr2, aLine2Delta ); + xConnector->setPropertyValue(aStr3, aLine3Delta ); + } + } + mpImpl->maConnections.clear(); + } +} + +SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport ) +{ + UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport ); + UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory ); + SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport ); + + // chain text attributes + pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) ); + return pResult; +} + +/** creates a shape property set mapper that can be used for non shape elements. + Only current feature is that the ShapeUserDefinedAttributes property is not included in this one. */ +SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateExternalShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport ) +{ + UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport ); + UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory, 1 ); + SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport ); + + // chain text attributes + pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) ); + return pResult; +} + +/** adds a mapping for a glue point identifier from an xml file to the identifier created after inserting + the new glue point into the core. The saved mappings can be retrieved by getGluePointId() */ +void XMLShapeImportHelper::addGluePointMapping( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, + sal_Int32 nSourceId, sal_Int32 nDestinnationId ) +{ + if( mpPageContext ) + mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId; +} + +/** moves all current DestinationId's by n */ +void XMLShapeImportHelper::moveGluePointMapping( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, const sal_Int32 n ) +{ + if( mpPageContext ) + { + ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) ); + if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() ) + { + GluePointIdMap::iterator aShapeIdIter = (*aShapeIter).second.begin(); + GluePointIdMap::iterator aShapeIdEnd = (*aShapeIter).second.end(); + while ( aShapeIdIter != aShapeIdEnd ) + { + if ( (*aShapeIdIter).second != -1 ) + (*aShapeIdIter).second += n; + aShapeIdIter++; + } + } + } +} + +/** retrieves a mapping for a glue point identifier from the current xml file to the identifier created after + inserting the new glue point into the core. The mapping must be initialized first with addGluePointMapping() */ +sal_Int32 XMLShapeImportHelper::getGluePointId( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId ) +{ + if( mpPageContext ) + { + ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) ); + if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() ) + { + GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId); + if( aIdIter != (*aShapeIter).second.end() ) + return (*aIdIter).second; + } + } + + return -1; +} + +/** this method must be calling before the first shape is imported for the given page */ +void XMLShapeImportHelper::startPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes ) +{ + XMLShapeImportPageContextImpl* pOldContext = mpPageContext; + mpPageContext = new XMLShapeImportPageContextImpl(); + mpPageContext->mpNext = pOldContext; + mpPageContext->mxShapes = rShapes; +} + +/** this method must be calling after the last shape is imported for the given page */ +void XMLShapeImportHelper::endPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& +#ifdef DBG_UTIL +rShapes +#endif +) +{ + DBG_ASSERT( mpPageContext && (mpPageContext->mxShapes == rShapes), "wrong call to endPage(), no startPage called or wrong page" ); + if( NULL == mpPageContext ) + return; + + restoreConnections(); + + XMLShapeImportPageContextImpl* pNextContext = mpPageContext->mpNext; + delete mpPageContext; + mpPageContext = pNextContext; +} + +// #88546# +/** defines if the import should increment the progress bar or not */ +void XMLShapeImportHelper::enableHandleProgressBar( sal_Bool bEnable ) +{ + mpImpl->mbHandleProgressBar = bEnable; +} + +sal_Bool XMLShapeImportHelper::IsHandleProgressBarEnabled() const +{ + return mpImpl->mbHandleProgressBar; +} + +/** queries the capability of the current model to create presentation shapes */ +sal_Bool XMLShapeImportHelper::IsPresentationShapesSupported() +{ + return mpImpl->mbIsPresentationShapesSupported; +} + +const rtl::Reference< XMLTableImport >& XMLShapeImportHelper::GetShapeTableImport() +{ + if( !mxShapeTableImport.is() ) + { + rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrImporter.GetModel(), mrImporter ) ); + rtl::Reference< XMLPropertySetMapper > xPropertySetMapper( new XMLShapePropertySetMapper( xFactory.get() ) ); + mxShapeTableImport = new XMLTableImport( mrImporter, xPropertySetMapper, xFactory ); + } + + return mxShapeTableImport; +} + +void SvXMLShapeContext::setHyperlink( const OUString& rHyperlink ) +{ + msHyperlink = rHyperlink; +} |