Bump for 4.0-11
[LibreOffice.git] / xmloff / source / draw / shapeimport.cxx
bloba08a2e9fbf9f89861468823e90423f0df6f53ca2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/debug.hxx>
23 #include <com/sun/star/text/PositionLayoutDir.hpp>
24 #include <com/sun/star/chart/XChartDocument.hpp>
26 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
28 #include <list>
30 #include <xmloff/shapeimport.hxx>
31 #include <xmloff/xmltkmap.hxx>
32 #include "xmloff/xmlnmspe.hxx"
33 #include <xmloff/xmltoken.hxx>
34 #include "ximpstyl.hxx"
35 #include "ximpshap.hxx"
36 #include "sdpropls.hxx"
37 #include <xmloff/xmlprmap.hxx>
38 #include "ximp3dscene.hxx"
39 #include "ximp3dobject.hxx"
40 #include "ximpgrp.hxx"
41 #include "ximplink.hxx"
43 #include <map>
44 #include <vector>
46 using ::rtl::OUString;
47 using ::rtl::OUStringBuffer;
49 using namespace ::std;
50 using namespace ::com::sun::star;
51 using namespace ::xmloff::token;
53 //////////////////////////////////////////////////////////////////////////////
55 struct ltint32
57 bool operator()(const sal_Int32 p, sal_Int32 q) const
59 return p < q;
63 typedef std::map<sal_Int32,com::sun::star::uno::Reference< com::sun::star::drawing::XShape >,ltint32> IdShapeMap;
65 struct ConnectionHint
67 com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxConnector;
68 sal_Bool bStart;
69 OUString aDestShapeId;
70 sal_Int32 nDestGlueId;
73 struct XShapeCompareHelper
75 bool operator()(com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x1,
76 com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x2 ) const
78 return x1.get() < x2.get();
82 /** this map store all glue point id mappings for shapes that had user defined glue points. This
83 is needed because on insertion the glue points will get a new and unique id */
84 typedef std::map<sal_Int32,sal_Int32,ltint32> GluePointIdMap;
85 typedef std::map< com::sun::star::uno::Reference < com::sun::star::drawing::XShape >, GluePointIdMap, XShapeCompareHelper > ShapeGluePointsMap;
87 /** this struct is created for each startPage() call and stores information that is needed during
88 import of shapes for one page. Since pages could be nested ( notes pages inside impress ) there
89 is a pointer so one can build up a stack of this structs */
90 struct XMLShapeImportPageContextImpl
92 ShapeGluePointsMap maShapeGluePointsMap;
94 uno::Reference < drawing::XShapes > mxShapes;
96 struct XMLShapeImportPageContextImpl* mpNext;
99 /** this class is to enable adding members to the XMLShapeImportHelper without getting incompatible */
100 struct XMLShapeImportHelperImpl
102 // context for sorting shapes
103 ShapeSortContext* mpSortContext;
105 IdShapeMap maShapeIds;
107 std::vector<ConnectionHint> maConnections;
109 // #88546# possibility to swich progress bar handling on/off
110 sal_Bool mbHandleProgressBar;
112 // stores the capability of the current model to create presentation shapes
113 sal_Bool mbIsPresentationShapesSupported;
116 //////////////////////////////////////////////////////////////////////////////
118 XMLShapeImportHelper::XMLShapeImportHelper(
119 SvXMLImport& rImporter,
120 const uno::Reference< frame::XModel>& rModel,
121 SvXMLImportPropertyMapper *pExtMapper )
122 : mpPageContext(NULL),
123 mxModel(rModel),
125 mpPropertySetMapper(0L),
126 mpPresPagePropsMapper(0L),
127 mpStylesContext(0L),
128 mpAutoStylesContext(0L),
129 mpGroupShapeElemTokenMap(0L),
130 mpFrameShapeElemTokenMap(0L),
131 mp3DSceneShapeElemTokenMap(0L),
132 mp3DObjectAttrTokenMap(0L),
133 mp3DPolygonBasedAttrTokenMap(0L),
134 mp3DCubeObjectAttrTokenMap(0L),
135 mp3DSphereObjectAttrTokenMap(0L),
136 mp3DSceneShapeAttrTokenMap(0L),
137 mp3DLightAttrTokenMap(0L),
138 mpPathShapeAttrTokenMap(0L),
139 mpPolygonShapeAttrTokenMap(0L),
140 msStartShape(RTL_CONSTASCII_USTRINGPARAM("StartShape")),
141 msEndShape(RTL_CONSTASCII_USTRINGPARAM("EndShape")),
142 msStartGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("StartGluePointIndex")),
143 msEndGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("EndGluePointIndex")),
145 mrImporter( rImporter )
147 mpImpl = new XMLShapeImportHelperImpl();
148 mpImpl->mpSortContext = 0;
150 // #88546# init to sal_False
151 mpImpl->mbHandleProgressBar = sal_False;
153 mpSdPropHdlFactory = new XMLSdPropHdlFactory( rModel, rImporter );
155 // set lock to avoid deletion
156 mpSdPropHdlFactory->acquire();
158 // construct PropertySetMapper
159 UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper(mpSdPropHdlFactory);
160 mpPropertySetMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
161 // set lock to avoid deletion
162 mpPropertySetMapper->acquire();
164 if( pExtMapper )
166 UniReference < SvXMLImportPropertyMapper > xExtMapper( pExtMapper );
167 mpPropertySetMapper->ChainImportMapper( xExtMapper );
170 // chain text attributes
171 mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImporter));
172 mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaDefaultExtPropMapper(rImporter));
174 // construct PresPagePropsMapper
175 xMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLSDPresPageProps, mpSdPropHdlFactory);
176 mpPresPagePropsMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
177 if(mpPresPagePropsMapper)
179 // set lock to avoid deletion
180 mpPresPagePropsMapper->acquire();
183 uno::Reference< lang::XServiceInfo > xInfo( rImporter.GetModel(), uno::UNO_QUERY );
184 const OUString aSName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument") );
185 mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService( aSName );
188 //////////////////////////////////////////////////////////////////////////////
190 XMLShapeImportHelper::~XMLShapeImportHelper()
192 DBG_ASSERT( mpImpl->maConnections.empty(), "XMLShapeImportHelper::restoreConnections() was not called!" );
194 // cleanup factory, decrease refcount. Should lead to destruction.
195 if(mpSdPropHdlFactory)
197 mpSdPropHdlFactory->release();
198 mpSdPropHdlFactory = 0L;
201 // cleanup mapper, decrease refcount. Should lead to destruction.
202 if(mpPropertySetMapper)
204 mpPropertySetMapper->release();
205 mpPropertySetMapper = 0L;
208 // cleanup presPage mapper, decrease refcount. Should lead to destruction.
209 if(mpPresPagePropsMapper)
211 mpPresPagePropsMapper->release();
212 mpPresPagePropsMapper = 0L;
215 if(mpGroupShapeElemTokenMap) delete mpGroupShapeElemTokenMap;
216 if(mpFrameShapeElemTokenMap) delete mpFrameShapeElemTokenMap;
218 if(mpPolygonShapeAttrTokenMap) delete mpPolygonShapeAttrTokenMap;
219 if(mpPathShapeAttrTokenMap) delete mpPathShapeAttrTokenMap;
220 if(mp3DSceneShapeElemTokenMap) delete mp3DSceneShapeElemTokenMap;
221 if(mp3DObjectAttrTokenMap) delete mp3DObjectAttrTokenMap;
222 if(mp3DPolygonBasedAttrTokenMap) delete mp3DPolygonBasedAttrTokenMap;
223 if(mp3DCubeObjectAttrTokenMap) delete mp3DCubeObjectAttrTokenMap;
224 if(mp3DSphereObjectAttrTokenMap) delete mp3DSphereObjectAttrTokenMap;
225 if(mp3DSceneShapeAttrTokenMap) delete mp3DSceneShapeAttrTokenMap;
226 if(mp3DLightAttrTokenMap) delete mp3DLightAttrTokenMap;
228 // Styles or AutoStyles context?
229 if(mpStylesContext)
231 mpStylesContext->Clear();
232 mpStylesContext->ReleaseRef();
235 if(mpAutoStylesContext)
237 mpAutoStylesContext->Clear();
238 mpAutoStylesContext->ReleaseRef();
241 delete mpImpl;
244 //////////////////////////////////////////////////////////////////////////////
248 const SvXMLTokenMap& XMLShapeImportHelper::GetGroupShapeElemTokenMap()
250 if(!mpGroupShapeElemTokenMap)
252 static SvXMLTokenMapEntry aGroupShapeElemTokenMap[] =
254 { XML_NAMESPACE_DRAW, XML_G, XML_TOK_GROUP_GROUP },
255 { XML_NAMESPACE_DRAW, XML_RECT, XML_TOK_GROUP_RECT },
256 { XML_NAMESPACE_DRAW, XML_LINE, XML_TOK_GROUP_LINE },
257 { XML_NAMESPACE_DRAW, XML_CIRCLE, XML_TOK_GROUP_CIRCLE },
258 { XML_NAMESPACE_DRAW, XML_ELLIPSE, XML_TOK_GROUP_ELLIPSE },
259 { XML_NAMESPACE_DRAW, XML_POLYGON, XML_TOK_GROUP_POLYGON },
260 { XML_NAMESPACE_DRAW, XML_POLYLINE, XML_TOK_GROUP_POLYLINE },
261 { XML_NAMESPACE_DRAW, XML_PATH, XML_TOK_GROUP_PATH },
263 { XML_NAMESPACE_DRAW, XML_CONTROL, XML_TOK_GROUP_CONTROL },
264 { XML_NAMESPACE_DRAW, XML_CONNECTOR, XML_TOK_GROUP_CONNECTOR },
265 { XML_NAMESPACE_DRAW, XML_MEASURE, XML_TOK_GROUP_MEASURE },
266 { XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, XML_TOK_GROUP_PAGE },
267 { XML_NAMESPACE_DRAW, XML_CAPTION, XML_TOK_GROUP_CAPTION },
269 { XML_NAMESPACE_CHART, XML_CHART, XML_TOK_GROUP_CHART },
270 { XML_NAMESPACE_DR3D, XML_SCENE, XML_TOK_GROUP_3DSCENE },
272 { XML_NAMESPACE_DRAW, XML_FRAME, XML_TOK_GROUP_FRAME },
273 { XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, XML_TOK_GROUP_CUSTOM_SHAPE },
275 { XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, XML_TOK_GROUP_CUSTOM_SHAPE },
276 { XML_NAMESPACE_OFFICE, XML_ANNOTATION, XML_TOK_GROUP_ANNOTATION },
277 { XML_NAMESPACE_DRAW, XML_A, XML_TOK_GROUP_A },
279 XML_TOKEN_MAP_END
282 mpGroupShapeElemTokenMap = new SvXMLTokenMap(aGroupShapeElemTokenMap);
283 } // if(!mpGroupShapeElemTokenMap)
285 return *mpGroupShapeElemTokenMap;
288 const SvXMLTokenMap& XMLShapeImportHelper::GetFrameShapeElemTokenMap()
290 if(!mpFrameShapeElemTokenMap)
292 static SvXMLTokenMapEntry aFrameShapeElemTokenMap[] =
294 { XML_NAMESPACE_DRAW, XML_TEXT_BOX, XML_TOK_FRAME_TEXT_BOX },
295 { XML_NAMESPACE_DRAW, XML_IMAGE, XML_TOK_FRAME_IMAGE },
296 { XML_NAMESPACE_DRAW, XML_OBJECT, XML_TOK_FRAME_OBJECT },
297 { XML_NAMESPACE_DRAW, XML_OBJECT_OLE, XML_TOK_FRAME_OBJECT_OLE },
298 { XML_NAMESPACE_DRAW, XML_PLUGIN, XML_TOK_FRAME_PLUGIN },
299 { XML_NAMESPACE_DRAW, XML_FLOATING_FRAME, XML_TOK_FRAME_FLOATING_FRAME},
300 { XML_NAMESPACE_DRAW, XML_APPLET, XML_TOK_FRAME_APPLET },
301 { XML_NAMESPACE_TABLE, XML_TABLE, XML_TOK_FRAME_TABLE },
302 XML_TOKEN_MAP_END
305 mpFrameShapeElemTokenMap = new SvXMLTokenMap(aFrameShapeElemTokenMap);
306 } // if(!mpFrameShapeElemTokenMap)
308 return *mpFrameShapeElemTokenMap;
311 //////////////////////////////////////////////////////////////////////////////
314 const SvXMLTokenMap& XMLShapeImportHelper::Get3DSceneShapeElemTokenMap()
316 if(!mp3DSceneShapeElemTokenMap)
318 static SvXMLTokenMapEntry a3DSceneShapeElemTokenMap[] =
320 { XML_NAMESPACE_DR3D, XML_SCENE, XML_TOK_3DSCENE_3DSCENE },
321 { XML_NAMESPACE_DR3D, XML_CUBE, XML_TOK_3DSCENE_3DCUBE },
322 { XML_NAMESPACE_DR3D, XML_SPHERE, XML_TOK_3DSCENE_3DSPHERE },
323 { XML_NAMESPACE_DR3D, XML_ROTATE, XML_TOK_3DSCENE_3DLATHE },
324 { XML_NAMESPACE_DR3D, XML_EXTRUDE, XML_TOK_3DSCENE_3DEXTRUDE },
325 XML_TOKEN_MAP_END
328 mp3DSceneShapeElemTokenMap = new SvXMLTokenMap(a3DSceneShapeElemTokenMap);
329 } // if(!mp3DSceneShapeElemTokenMap)
331 return *mp3DSceneShapeElemTokenMap;
334 //////////////////////////////////////////////////////////////////////////////
337 const SvXMLTokenMap& XMLShapeImportHelper::Get3DObjectAttrTokenMap()
339 if(!mp3DObjectAttrTokenMap)
341 static SvXMLTokenMapEntry a3DObjectAttrTokenMap[] =
343 { XML_NAMESPACE_DRAW, XML_STYLE_NAME, XML_TOK_3DOBJECT_DRAWSTYLE_NAME },
344 { XML_NAMESPACE_DR3D, XML_TRANSFORM, XML_TOK_3DOBJECT_TRANSFORM },
345 XML_TOKEN_MAP_END
348 mp3DObjectAttrTokenMap = new SvXMLTokenMap(a3DObjectAttrTokenMap);
349 } // if(!mp3DObjectAttrTokenMap)
351 return *mp3DObjectAttrTokenMap;
354 //////////////////////////////////////////////////////////////////////////////
357 const SvXMLTokenMap& XMLShapeImportHelper::Get3DPolygonBasedAttrTokenMap()
359 if(!mp3DPolygonBasedAttrTokenMap)
361 static SvXMLTokenMapEntry a3DPolygonBasedAttrTokenMap[] =
363 { XML_NAMESPACE_SVG, XML_VIEWBOX, XML_TOK_3DPOLYGONBASED_VIEWBOX },
364 { XML_NAMESPACE_SVG, XML_D, XML_TOK_3DPOLYGONBASED_D },
365 XML_TOKEN_MAP_END
368 mp3DPolygonBasedAttrTokenMap = new SvXMLTokenMap(a3DPolygonBasedAttrTokenMap);
369 } // if(!mp3DPolygonBasedAttrTokenMap)
371 return *mp3DPolygonBasedAttrTokenMap;
374 //////////////////////////////////////////////////////////////////////////////
377 const SvXMLTokenMap& XMLShapeImportHelper::Get3DCubeObjectAttrTokenMap()
379 if(!mp3DCubeObjectAttrTokenMap)
381 static SvXMLTokenMapEntry a3DCubeObjectAttrTokenMap[] =
383 { XML_NAMESPACE_DR3D, XML_MIN_EDGE, XML_TOK_3DCUBEOBJ_MINEDGE },
384 { XML_NAMESPACE_DR3D, XML_MAX_EDGE, XML_TOK_3DCUBEOBJ_MAXEDGE },
385 XML_TOKEN_MAP_END
388 mp3DCubeObjectAttrTokenMap = new SvXMLTokenMap(a3DCubeObjectAttrTokenMap);
389 } // if(!mp3DCubeObjectAttrTokenMap)
391 return *mp3DCubeObjectAttrTokenMap;
394 //////////////////////////////////////////////////////////////////////////////
397 const SvXMLTokenMap& XMLShapeImportHelper::Get3DSphereObjectAttrTokenMap()
399 if(!mp3DSphereObjectAttrTokenMap)
401 static SvXMLTokenMapEntry a3DSphereObjectAttrTokenMap[] =
403 { XML_NAMESPACE_DR3D, XML_CENTER, XML_TOK_3DSPHEREOBJ_CENTER },
404 { XML_NAMESPACE_DR3D, XML_SIZE, XML_TOK_3DSPHEREOBJ_SIZE },
405 XML_TOKEN_MAP_END
408 mp3DSphereObjectAttrTokenMap = new SvXMLTokenMap(a3DSphereObjectAttrTokenMap);
409 } // if(!mp3DSphereObjectAttrTokenMap)
411 return *mp3DSphereObjectAttrTokenMap;
414 //////////////////////////////////////////////////////////////////////////////
416 const SvXMLTokenMap& XMLShapeImportHelper::Get3DLightAttrTokenMap()
418 if(!mp3DLightAttrTokenMap)
420 static SvXMLTokenMapEntry a3DLightAttrTokenMap[] =
422 { XML_NAMESPACE_DR3D, XML_DIFFUSE_COLOR, XML_TOK_3DLIGHT_DIFFUSE_COLOR },
423 { XML_NAMESPACE_DR3D, XML_DIRECTION, XML_TOK_3DLIGHT_DIRECTION },
424 { XML_NAMESPACE_DR3D, XML_ENABLED, XML_TOK_3DLIGHT_ENABLED },
425 { XML_NAMESPACE_DR3D, XML_SPECULAR, XML_TOK_3DLIGHT_SPECULAR },
426 XML_TOKEN_MAP_END
429 mp3DLightAttrTokenMap = new SvXMLTokenMap(a3DLightAttrTokenMap);
430 } // if(!mp3DLightAttrTokenMap)
432 return *mp3DLightAttrTokenMap;
435 //////////////////////////////////////////////////////////////////////////////
438 SvXMLShapeContext* XMLShapeImportHelper::Create3DSceneChildContext(
439 SvXMLImport& rImport,
440 sal_uInt16 p_nPrefix,
441 const OUString& rLocalName,
442 const uno::Reference< xml::sax::XAttributeList>& xAttrList,
443 uno::Reference< drawing::XShapes >& rShapes)
445 SdXMLShapeContext *pContext = 0L;
447 if(rShapes.is())
449 const SvXMLTokenMap& rTokenMap = Get3DSceneShapeElemTokenMap();
450 switch(rTokenMap.Get(p_nPrefix, rLocalName))
452 case XML_TOK_3DSCENE_3DSCENE:
454 // dr3d:3dscene inside dr3d:3dscene context
455 pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
456 break;
458 case XML_TOK_3DSCENE_3DCUBE:
460 // dr3d:3dcube inside dr3d:3dscene context
461 pContext = new SdXML3DCubeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
462 break;
464 case XML_TOK_3DSCENE_3DSPHERE:
466 // dr3d:3dsphere inside dr3d:3dscene context
467 pContext = new SdXML3DSphereObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
468 break;
470 case XML_TOK_3DSCENE_3DLATHE:
472 // dr3d:3dlathe inside dr3d:3dscene context
473 pContext = new SdXML3DLatheObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
474 break;
476 case XML_TOK_3DSCENE_3DEXTRUDE:
478 // dr3d:3dextrude inside dr3d:3dscene context
479 pContext = new SdXML3DExtrudeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
480 break;
485 // now parse the attribute list and call the child context for each unknown attribute
486 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
487 for(sal_Int16 a(0); a < nAttrCount; a++)
489 const OUString& rAttrName = xAttrList->getNameByIndex(a);
490 OUString aLocalName;
491 sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
492 const OUString aValue( xAttrList->getValueByIndex(a) );
494 pContext->processAttribute( nPrefix, aLocalName, aValue );
497 return pContext;
500 //////////////////////////////////////////////////////////////////////////////
502 void XMLShapeImportHelper::SetStylesContext(SvXMLStylesContext* pNew)
504 mpStylesContext = pNew;
505 mpStylesContext->AddRef();
508 //////////////////////////////////////////////////////////////////////////////
510 void XMLShapeImportHelper::SetAutoStylesContext(SvXMLStylesContext* pNew)
512 mpAutoStylesContext = pNew;
513 mpAutoStylesContext->AddRef();
516 //////////////////////////////////////////////////////////////////////////////
518 SvXMLShapeContext* XMLShapeImportHelper::CreateGroupChildContext(
519 SvXMLImport& rImport,
520 sal_uInt16 p_nPrefix,
521 const OUString& rLocalName,
522 const uno::Reference< xml::sax::XAttributeList>& xAttrList,
523 uno::Reference< drawing::XShapes >& rShapes,
524 sal_Bool bTemporaryShape)
526 SdXMLShapeContext *pContext = 0L;
528 const SvXMLTokenMap& rTokenMap = GetGroupShapeElemTokenMap();
529 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
531 switch(rTokenMap.Get(p_nPrefix, rLocalName))
533 case XML_TOK_GROUP_GROUP:
535 // draw:g inside group context (RECURSIVE)
536 pContext = new SdXMLGroupShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
537 break;
539 case XML_TOK_GROUP_3DSCENE:
541 // dr3d:3dscene inside group context
542 pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
543 break;
545 case XML_TOK_GROUP_RECT:
547 // draw:rect inside group context
548 pContext = new SdXMLRectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
549 break;
551 case XML_TOK_GROUP_LINE:
553 // draw:line inside group context
554 pContext = new SdXMLLineShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
555 break;
557 case XML_TOK_GROUP_CIRCLE:
558 case XML_TOK_GROUP_ELLIPSE:
560 // draw:circle or draw:ellipse inside group context
561 pContext = new SdXMLEllipseShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
562 break;
564 case XML_TOK_GROUP_POLYGON:
565 case XML_TOK_GROUP_POLYLINE:
567 // draw:polygon or draw:polyline inside group context
568 pContext = new SdXMLPolygonShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes,
569 rTokenMap.Get(p_nPrefix, rLocalName) == XML_TOK_GROUP_POLYGON ? sal_True : sal_False, bTemporaryShape );
570 break;
572 case XML_TOK_GROUP_PATH:
574 // draw:path inside group context
575 pContext = new SdXMLPathShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
576 break;
578 case XML_TOK_GROUP_FRAME:
580 // text:text-box inside group context
581 pContext = new SdXMLFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
582 break;
584 case XML_TOK_GROUP_CONTROL:
586 // draw:control inside group context
587 pContext = new SdXMLControlShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
588 break;
590 case XML_TOK_GROUP_CONNECTOR:
592 // draw:connector inside group context
593 pContext = new SdXMLConnectorShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
594 break;
596 case XML_TOK_GROUP_MEASURE:
598 // draw:measure inside group context
599 pContext = new SdXMLMeasureShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
600 break;
602 case XML_TOK_GROUP_PAGE:
604 // draw:page inside group context
605 pContext = new SdXMLPageShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
606 break;
608 case XML_TOK_GROUP_CAPTION:
609 case XML_TOK_GROUP_ANNOTATION:
611 // draw:caption inside group context
612 pContext = new SdXMLCaptionShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
613 break;
615 case XML_TOK_GROUP_CHART:
617 // chart:chart inside group context
618 pContext = new SdXMLChartShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
619 break;
621 case XML_TOK_GROUP_CUSTOM_SHAPE:
623 // draw:customshape
624 pContext = new SdXMLCustomShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
625 break;
627 case XML_TOK_GROUP_A:
629 return new SdXMLShapeLinkContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes );
631 // add other shapes here...
632 default:
633 return new SvXMLShapeContext( rImport, p_nPrefix, rLocalName, bTemporaryShape );
636 // now parse the attribute list and call the child context for each unknown attribute
637 for(sal_Int16 a(0); a < nAttrCount; a++)
639 const OUString& rAttrName = xAttrList->getNameByIndex(a);
640 OUString aLocalName;
641 sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
642 const OUString aValue( xAttrList->getValueByIndex(a) );
644 pContext->processAttribute( nPrefix, aLocalName, aValue );
647 return pContext;
650 // This method is called from SdXMLFrameContext to create children of drawe:frame
651 SvXMLShapeContext* XMLShapeImportHelper::CreateFrameChildContext(
652 SvXMLImport& rImport,
653 sal_uInt16 p_nPrefix,
654 const OUString& rLocalName,
655 const uno::Reference< xml::sax::XAttributeList>& rAttrList,
656 uno::Reference< drawing::XShapes >& rShapes,
657 const uno::Reference< xml::sax::XAttributeList>& rFrameAttrList)
659 SdXMLShapeContext *pContext = 0L;
661 const SvXMLTokenMap& rTokenMap = GetFrameShapeElemTokenMap();
663 SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList );
664 if( rFrameAttrList.is() )
665 pAttrList->AppendAttributeList( rFrameAttrList );
666 uno::Reference < xml::sax::XAttributeList > xAttrList = pAttrList;
669 switch(rTokenMap.Get(p_nPrefix, rLocalName))
671 case XML_TOK_FRAME_TEXT_BOX:
673 // text:text-box inside group context
674 pContext = new SdXMLTextBoxShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
675 break;
677 case XML_TOK_FRAME_IMAGE:
679 // office:image inside group context
680 pContext = new SdXMLGraphicObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
681 break;
683 case XML_TOK_FRAME_OBJECT:
684 case XML_TOK_FRAME_OBJECT_OLE:
686 // draw:object or draw:object_ole
687 pContext = new SdXMLObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
688 break;
690 case XML_TOK_FRAME_TABLE:
692 // draw:object or draw:object_ole
693 if( rImport.IsTableShapeSupported() )
694 pContext = new SdXMLTableShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes );
695 break;
698 case XML_TOK_FRAME_PLUGIN:
700 // draw:plugin
701 pContext = new SdXMLPluginShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
702 break;
704 case XML_TOK_FRAME_FLOATING_FRAME:
706 // draw:floating-frame
707 pContext = new SdXMLFloatingFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
708 break;
710 case XML_TOK_FRAME_APPLET:
712 // draw:applet
713 pContext = new SdXMLAppletShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
714 break;
716 // add other shapes here...
717 default:
718 break;
721 if( pContext )
723 // now parse the attribute list and call the child context for each unknown attribute
724 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
725 for(sal_Int16 a(0); a < nAttrCount; a++)
727 const OUString& rAttrName = xAttrList->getNameByIndex(a);
728 OUString aLocalName;
729 sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
730 const OUString aValue( xAttrList->getValueByIndex(a) );
732 pContext->processAttribute( nPrefix, aLocalName, aValue );
736 return pContext;
739 SvXMLImportContext *XMLShapeImportHelper::CreateFrameChildContext(
740 SvXMLImportContext *pThisContext,
741 sal_uInt16 nPrefix,
742 const OUString& rLocalName,
743 const uno::Reference< xml::sax::XAttributeList>& xAttrList )
745 SvXMLImportContext * pContext = NULL;
747 SdXMLFrameShapeContext *pFrameContext = PTR_CAST( SdXMLFrameShapeContext, pThisContext );
748 if( pFrameContext )
749 pContext = pFrameContext->CreateChildContext( nPrefix, rLocalName, xAttrList );
751 return pContext;
755 /** this function is called whenever the implementation classes like to add this new
756 shape to the given XShapes.
758 void XMLShapeImportHelper::addShape( uno::Reference< drawing::XShape >& rShape,
759 const uno::Reference< xml::sax::XAttributeList >&,
760 uno::Reference< drawing::XShapes >& rShapes)
762 if( rShape.is() && rShapes.is() )
764 // add new shape to parent
765 rShapes->add( rShape );
769 /** this function is called whenever the implementation classes have finished importing
770 a shape to the given XShapes. The shape is already inserted into its XShapes and
771 all properties and styles are set.
773 void XMLShapeImportHelper::finishShape(
774 com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape,
775 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >&,
776 com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >&)
778 /* Set property <PositionLayoutDir>
779 to <PositionInHoriL2R>, if it exists and the import states that
780 the shape positioning attributes are in horizontal left-to-right
781 layout. This is the case for the OpenOffice.org file format.
782 This setting is done for Writer documents, because the property
783 only exists at service com::sun::star::text::Shape - the Writer
784 UNO service for shapes.
785 The value indicates that the positioning attributes are given
786 in horizontal left-to-right layout. The property is evaluated
787 during the first positioning of the shape in order to convert
788 the shape position given in the OpenOffice.org file format to
789 the one for the OASIS Open Office file format. (#i28749#, #i36248#)
791 uno::Reference< beans::XPropertySet > xPropSet(rShape, uno::UNO_QUERY);
792 if ( xPropSet.is() )
794 if ( mrImporter.IsShapePositionInHoriL2R() &&
795 xPropSet->getPropertySetInfo()->hasPropertyByName(
796 OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir"))) )
798 uno::Any aPosLayoutDir;
799 aPosLayoutDir <<= text::PositionLayoutDir::PositionInHoriL2R;
800 xPropSet->setPropertyValue(
801 OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir")),
802 aPosLayoutDir );
807 // helper functions for z-order sorting
808 struct ZOrderHint
810 sal_Int32 nIs;
811 sal_Int32 nShould;
813 int operator<(const ZOrderHint& rComp) const { return nShould < rComp.nShould; }
816 class ShapeSortContext
818 public:
819 uno::Reference< drawing::XShapes > mxShapes;
820 list<ZOrderHint> maZOrderList;
821 list<ZOrderHint> maUnsortedList;
823 sal_Int32 mnCurrentZ;
824 ShapeSortContext* mpParentContext;
825 const OUString msZOrder;
827 ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext = NULL );
829 void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos );
832 ShapeSortContext::ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext )
833 : mxShapes( rShapes ), mnCurrentZ( 0 ), mpParentContext( pParentContext ),
834 msZOrder(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))
838 void ShapeSortContext::moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos )
840 uno::Any aAny( mxShapes->getByIndex( nSourcePos ) );
841 uno::Reference< beans::XPropertySet > xPropSet;
842 aAny >>= xPropSet;
844 if( xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName( msZOrder ) )
846 aAny <<= nDestPos;
847 xPropSet->setPropertyValue( msZOrder, aAny );
849 list<ZOrderHint>::iterator aIter = maZOrderList.begin();
850 list<ZOrderHint>::iterator aEnd = maZOrderList.end();
852 while( aIter != aEnd )
854 if( (*aIter).nIs < nSourcePos )
856 DBG_ASSERT( (*aIter).nIs >= nDestPos, "Shape sorting failed" );
857 (*aIter).nIs++;
859 ++aIter;
862 aIter = maUnsortedList.begin();
863 aEnd = maUnsortedList.end();
865 while( aIter != aEnd )
867 if( (*aIter).nIs < nSourcePos )
869 DBG_ASSERT( (*aIter).nIs >= nDestPos, "shape sorting failed" );
870 (*aIter).nIs++;
872 ++aIter;
877 void XMLShapeImportHelper::pushGroupForSorting( uno::Reference< drawing::XShapes >& rShapes )
879 mpImpl->mpSortContext = new ShapeSortContext( rShapes, mpImpl->mpSortContext );
882 void XMLShapeImportHelper::popGroupAndSort()
884 DBG_ASSERT( mpImpl->mpSortContext, "No context to sort!" );
885 if( mpImpl->mpSortContext == NULL )
886 return;
890 list<ZOrderHint>& rZList = mpImpl->mpSortContext->maZOrderList;
891 list<ZOrderHint>& rUnsortedList = mpImpl->mpSortContext->maUnsortedList;
893 // sort shapes
894 if( !rZList.empty() )
896 // only do something if we have shapes to sort
898 // check if there are more shapes than inserted with ::shapeWithZIndexAdded()
899 // This can happen if there where already shapes on the page before import
900 // Since the writer may delete some of this shapes during import, we need
901 // to do this here and not in our c'tor anymore
903 // check if we have more shapes than we know of
904 sal_Int32 nCount = mpImpl->mpSortContext->mxShapes->getCount();
906 nCount -= rZList.size();
907 nCount -= rUnsortedList.size();
910 if( nCount > 0 )
912 // first update offsets of added shapes
913 list<ZOrderHint>::iterator aIter( rZList.begin() );
914 while( aIter != rZList.end() )
915 (*aIter++).nIs += nCount;
917 aIter = rUnsortedList.begin();
918 while( aIter != rUnsortedList.end() )
919 (*aIter++).nIs += nCount;
921 // second add the already existing shapes in the unsorted list
922 ZOrderHint aNewHint;
926 nCount--;
928 aNewHint.nIs = nCount;
929 aNewHint.nShould = -1;
931 rUnsortedList.insert(rUnsortedList.begin(), aNewHint);
933 while( nCount );
936 // sort z ordered shapes
937 rZList.sort();
939 // this is the current index, all shapes before that
940 // index are finished
941 sal_Int32 nIndex = 0;
942 while( !rZList.empty() )
944 list<ZOrderHint>::iterator aIter( rZList.begin() );
946 while( nIndex < (*aIter).nShould && !rUnsortedList.empty() )
948 ZOrderHint aGapHint( *rUnsortedList.begin() );
949 rUnsortedList.pop_front();
951 mpImpl->mpSortContext->moveShape( aGapHint.nIs, nIndex++ );
954 if( (*aIter).nIs != nIndex )
955 mpImpl->mpSortContext->moveShape( (*aIter).nIs, nIndex );
957 rZList.pop_front();
958 nIndex++;
962 catch( uno::Exception& )
964 OSL_FAIL("exception while sorting shapes, sorting failed!");
967 // put parent on top and delete current context, were done
968 ShapeSortContext* pContext = mpImpl->mpSortContext;
969 mpImpl->mpSortContext = pContext->mpParentContext;
970 delete pContext;
973 void XMLShapeImportHelper::shapeWithZIndexAdded( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >&, sal_Int32 nZIndex )
975 if( mpImpl->mpSortContext)
977 ZOrderHint aNewHint;
978 aNewHint.nIs = mpImpl->mpSortContext->mnCurrentZ++;
979 aNewHint.nShould = nZIndex;
981 if( nZIndex == -1 )
983 // don't care, so add to unsorted list
984 mpImpl->mpSortContext->maUnsortedList.push_back(aNewHint);
986 else
988 // insert into sort list
989 mpImpl->mpSortContext->maZOrderList.push_back(aNewHint);
994 void XMLShapeImportHelper::addShapeConnection( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rConnectorShape,
995 sal_Bool bStart,
996 const rtl::OUString& rDestShapeId,
997 sal_Int32 nDestGlueId )
999 ConnectionHint aHint;
1000 aHint.mxConnector = rConnectorShape;
1001 aHint.bStart = bStart;
1002 aHint.aDestShapeId = rDestShapeId;
1003 aHint.nDestGlueId = nDestGlueId;
1005 mpImpl->maConnections.push_back( aHint );
1008 void XMLShapeImportHelper::restoreConnections()
1010 if( !mpImpl->maConnections.empty() )
1012 uno::Any aAny;
1014 const vector<ConnectionHint>::size_type nCount = mpImpl->maConnections.size();
1015 for( vector<ConnectionHint>::size_type i = 0; i < nCount; i++ )
1017 ConnectionHint& rHint = mpImpl->maConnections[i];
1018 uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY );
1019 if( xConnector.is() )
1021 // #86637# remember line deltas
1022 uno::Any aLine1Delta;
1023 uno::Any aLine2Delta;
1024 uno::Any aLine3Delta;
1025 OUString aStr1(RTL_CONSTASCII_USTRINGPARAM("EdgeLine1Delta"));
1026 OUString aStr2(RTL_CONSTASCII_USTRINGPARAM("EdgeLine2Delta"));
1027 OUString aStr3(RTL_CONSTASCII_USTRINGPARAM("EdgeLine3Delta"));
1028 aLine1Delta = xConnector->getPropertyValue(aStr1);
1029 aLine2Delta = xConnector->getPropertyValue(aStr2);
1030 aLine3Delta = xConnector->getPropertyValue(aStr3);
1032 // #86637# simply setting these values WILL force the connector to do
1033 // an new layout promptly. So the line delta values have to be rescued
1034 // and restored around connector changes.
1035 uno::Reference< drawing::XShape > xShape(
1036 mrImporter.getInterfaceToIdentifierMapper().getReference( rHint.aDestShapeId ), uno::UNO_QUERY );
1037 if( xShape.is() )
1039 aAny <<= xShape;
1040 xConnector->setPropertyValue( rHint.bStart ? msStartShape : msEndShape, aAny );
1042 sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId : getGluePointId( xShape, rHint.nDestGlueId );
1043 aAny <<= nGlueId;
1044 xConnector->setPropertyValue( rHint.bStart ? msStartGluePointIndex : msEndGluePointIndex, aAny );
1047 // #86637# restore line deltas
1048 xConnector->setPropertyValue(aStr1, aLine1Delta );
1049 xConnector->setPropertyValue(aStr2, aLine2Delta );
1050 xConnector->setPropertyValue(aStr3, aLine3Delta );
1053 mpImpl->maConnections.clear();
1057 SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport )
1059 UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport );
1060 UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory );
1061 SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport );
1063 // chain text attributes
1064 pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) );
1065 return pResult;
1068 /** adds a mapping for a glue point identifier from an xml file to the identifier created after inserting
1069 the new glue point into the core. The saved mappings can be retrieved by getGluePointId() */
1070 void XMLShapeImportHelper::addGluePointMapping( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape,
1071 sal_Int32 nSourceId, sal_Int32 nDestinnationId )
1073 if( mpPageContext )
1074 mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
1077 /** moves all current DestinationId's by n */
1078 void XMLShapeImportHelper::moveGluePointMapping( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, const sal_Int32 n )
1080 if( mpPageContext )
1082 ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
1083 if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
1085 GluePointIdMap::iterator aShapeIdIter = (*aShapeIter).second.begin();
1086 GluePointIdMap::iterator aShapeIdEnd = (*aShapeIter).second.end();
1087 while ( aShapeIdIter != aShapeIdEnd )
1089 if ( (*aShapeIdIter).second != -1 )
1090 (*aShapeIdIter).second += n;
1091 ++aShapeIdIter;
1097 /** retrieves a mapping for a glue point identifier from the current xml file to the identifier created after
1098 inserting the new glue point into the core. The mapping must be initialized first with addGluePointMapping() */
1099 sal_Int32 XMLShapeImportHelper::getGluePointId( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId )
1101 if( mpPageContext )
1103 ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
1104 if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
1106 GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId);
1107 if( aIdIter != (*aShapeIter).second.end() )
1108 return (*aIdIter).second;
1112 return -1;
1115 /** this method must be calling before the first shape is imported for the given page */
1116 void XMLShapeImportHelper::startPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes )
1118 XMLShapeImportPageContextImpl* pOldContext = mpPageContext;
1119 mpPageContext = new XMLShapeImportPageContextImpl();
1120 mpPageContext->mpNext = pOldContext;
1121 mpPageContext->mxShapes = rShapes;
1124 /** this method must be calling after the last shape is imported for the given page */
1125 void XMLShapeImportHelper::endPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >&
1126 #ifdef DBG_UTIL
1127 rShapes
1128 #endif
1131 DBG_ASSERT( mpPageContext && (mpPageContext->mxShapes == rShapes), "wrong call to endPage(), no startPage called or wrong page" );
1132 if( NULL == mpPageContext )
1133 return;
1135 restoreConnections();
1137 XMLShapeImportPageContextImpl* pNextContext = mpPageContext->mpNext;
1138 delete mpPageContext;
1139 mpPageContext = pNextContext;
1142 // #88546#
1143 /** defines if the import should increment the progress bar or not */
1144 void XMLShapeImportHelper::enableHandleProgressBar( sal_Bool bEnable )
1146 mpImpl->mbHandleProgressBar = bEnable;
1149 sal_Bool XMLShapeImportHelper::IsHandleProgressBarEnabled() const
1151 return mpImpl->mbHandleProgressBar;
1154 /** queries the capability of the current model to create presentation shapes */
1155 sal_Bool XMLShapeImportHelper::IsPresentationShapesSupported()
1157 return mpImpl->mbIsPresentationShapesSupported;
1160 const rtl::Reference< XMLTableImport >& XMLShapeImportHelper::GetShapeTableImport()
1162 if( !mxShapeTableImport.is() )
1164 rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrImporter.GetModel(), mrImporter ) );
1165 rtl::Reference< XMLPropertySetMapper > xPropertySetMapper( new XMLShapePropertySetMapper( xFactory.get() ) );
1166 mxShapeTableImport = new XMLTableImport( mrImporter, xPropertySetMapper, xFactory );
1169 return mxShapeTableImport;
1172 void SvXMLShapeContext::setHyperlink( const OUString& rHyperlink )
1174 msHyperlink = rHyperlink;
1177 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */