1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include <tools/debug.hxx>
22 #include <com/sun/star/text/PositionLayoutDir.hpp>
23 #include <com/sun/star/chart/XChartDocument.hpp>
25 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
26 #include <osl/diagnose.h>
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"
46 using namespace ::std
;
47 using namespace ::com::sun::star
;
48 using namespace ::xmloff::token
;
52 bool operator()(const sal_Int32 p
, sal_Int32 q
) const
58 typedef std::map
<sal_Int32
,com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>,ltint32
> IdShapeMap
;
62 com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> mxConnector
;
64 OUString aDestShapeId
;
65 sal_Int32 nDestGlueId
;
68 struct XShapeCompareHelper
70 bool operator()(com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> x1
,
71 com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> x2
) const
73 return x1
.get() < x2
.get();
77 /** this map store all glue point id mappings for shapes that had user defined glue points. This
78 is needed because on insertion the glue points will get a new and unique id */
79 typedef std::map
<sal_Int32
,sal_Int32
,ltint32
> GluePointIdMap
;
80 typedef std::map
< com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>, GluePointIdMap
, XShapeCompareHelper
> ShapeGluePointsMap
;
82 /** this struct is created for each startPage() call and stores information that is needed during
83 import of shapes for one page. Since pages could be nested ( notes pages inside impress ) there
84 is a pointer so one can build up a stack of this structs */
85 struct XMLShapeImportPageContextImpl
87 ShapeGluePointsMap maShapeGluePointsMap
;
89 uno::Reference
< drawing::XShapes
> mxShapes
;
91 struct XMLShapeImportPageContextImpl
* mpNext
;
94 /** this class is to enable adding members to the XMLShapeImportHelper without getting incompatible */
95 struct XMLShapeImportHelperImpl
97 // context for sorting shapes
98 ShapeSortContext
* mpSortContext
;
100 IdShapeMap maShapeIds
;
102 std::vector
<ConnectionHint
> maConnections
;
104 // #88546# possibility to switch progress bar handling on/off
105 bool mbHandleProgressBar
;
107 // stores the capability of the current model to create presentation shapes
108 bool mbIsPresentationShapesSupported
;
111 XMLShapeImportHelper::XMLShapeImportHelper(
112 SvXMLImport
& rImporter
,
113 const uno::Reference
< frame::XModel
>& rModel
,
114 SvXMLImportPropertyMapper
*pExtMapper
)
115 : mpPageContext(NULL
),
118 mpPropertySetMapper(0L),
119 mpPresPagePropsMapper(0L),
121 mpAutoStylesContext(0L),
122 mpGroupShapeElemTokenMap(0L),
123 mpFrameShapeElemTokenMap(0L),
124 mp3DSceneShapeElemTokenMap(0L),
125 mp3DObjectAttrTokenMap(0L),
126 mp3DPolygonBasedAttrTokenMap(0L),
127 mp3DCubeObjectAttrTokenMap(0L),
128 mp3DSphereObjectAttrTokenMap(0L),
129 mp3DSceneShapeAttrTokenMap(0L),
130 mp3DLightAttrTokenMap(0L),
131 mpPathShapeAttrTokenMap(0L),
132 mpPolygonShapeAttrTokenMap(0L),
133 msStartShape("StartShape"),
134 msEndShape("EndShape"),
135 msStartGluePointIndex("StartGluePointIndex"),
136 msEndGluePointIndex("EndGluePointIndex"),
138 mrImporter( rImporter
)
140 mpImpl
= new XMLShapeImportHelperImpl();
141 mpImpl
->mpSortContext
= 0;
143 // #88546# init to sal_False
144 mpImpl
->mbHandleProgressBar
= false;
146 mpSdPropHdlFactory
= new XMLSdPropHdlFactory( rModel
, rImporter
);
148 // set lock to avoid deletion
149 mpSdPropHdlFactory
->acquire();
151 // construct PropertySetMapper
152 rtl::Reference
< XMLPropertySetMapper
> xMapper
= new XMLShapePropertySetMapper(mpSdPropHdlFactory
, false);
153 mpPropertySetMapper
= new SvXMLImportPropertyMapper( xMapper
, rImporter
);
154 // set lock to avoid deletion
155 mpPropertySetMapper
->acquire();
159 rtl::Reference
< SvXMLImportPropertyMapper
> xExtMapper( pExtMapper
);
160 mpPropertySetMapper
->ChainImportMapper( xExtMapper
);
163 // chain text attributes
164 mpPropertySetMapper
->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImporter
));
165 mpPropertySetMapper
->ChainImportMapper(XMLTextImportHelper::CreateParaDefaultExtPropMapper(rImporter
));
167 // construct PresPagePropsMapper
168 xMapper
= new XMLPropertySetMapper(aXMLSDPresPageProps
, mpSdPropHdlFactory
, false);
169 mpPresPagePropsMapper
= new SvXMLImportPropertyMapper( xMapper
, rImporter
);
170 // set lock to avoid deletion
171 mpPresPagePropsMapper
->acquire();
173 uno::Reference
< lang::XServiceInfo
> xInfo( rImporter
.GetModel(), uno::UNO_QUERY
);
174 const OUString
aSName( "com.sun.star.presentation.PresentationDocument" );
175 mpImpl
->mbIsPresentationShapesSupported
= xInfo
.is() && xInfo
->supportsService( aSName
);
178 XMLShapeImportHelper::~XMLShapeImportHelper()
180 DBG_ASSERT( mpImpl
->maConnections
.empty(), "XMLShapeImportHelper::restoreConnections() was not called!" );
182 // cleanup factory, decrease refcount. Should lead to destruction.
183 if(mpSdPropHdlFactory
)
185 mpSdPropHdlFactory
->release();
186 mpSdPropHdlFactory
= 0L;
189 // cleanup mapper, decrease refcount. Should lead to destruction.
190 if(mpPropertySetMapper
)
192 mpPropertySetMapper
->release();
193 mpPropertySetMapper
= 0L;
196 // cleanup presPage mapper, decrease refcount. Should lead to destruction.
197 if(mpPresPagePropsMapper
)
199 mpPresPagePropsMapper
->release();
200 mpPresPagePropsMapper
= 0L;
203 if(mpGroupShapeElemTokenMap
) delete mpGroupShapeElemTokenMap
;
204 if(mpFrameShapeElemTokenMap
) delete mpFrameShapeElemTokenMap
;
206 if(mpPolygonShapeAttrTokenMap
) delete mpPolygonShapeAttrTokenMap
;
207 if(mpPathShapeAttrTokenMap
) delete mpPathShapeAttrTokenMap
;
208 if(mp3DSceneShapeElemTokenMap
) delete mp3DSceneShapeElemTokenMap
;
209 if(mp3DObjectAttrTokenMap
) delete mp3DObjectAttrTokenMap
;
210 if(mp3DPolygonBasedAttrTokenMap
) delete mp3DPolygonBasedAttrTokenMap
;
211 if(mp3DCubeObjectAttrTokenMap
) delete mp3DCubeObjectAttrTokenMap
;
212 if(mp3DSphereObjectAttrTokenMap
) delete mp3DSphereObjectAttrTokenMap
;
213 if(mp3DSceneShapeAttrTokenMap
) delete mp3DSceneShapeAttrTokenMap
;
214 if(mp3DLightAttrTokenMap
) delete mp3DLightAttrTokenMap
;
216 // Styles or AutoStyles context?
219 mpStylesContext
->Clear();
220 mpStylesContext
->ReleaseRef();
223 if(mpAutoStylesContext
)
225 mpAutoStylesContext
->Clear();
226 mpAutoStylesContext
->ReleaseRef();
232 const SvXMLTokenMap
& XMLShapeImportHelper::GetGroupShapeElemTokenMap()
234 if(!mpGroupShapeElemTokenMap
)
236 static const SvXMLTokenMapEntry aGroupShapeElemTokenMap
[] =
238 { XML_NAMESPACE_DRAW
, XML_G
, XML_TOK_GROUP_GROUP
},
239 { XML_NAMESPACE_DRAW
, XML_RECT
, XML_TOK_GROUP_RECT
},
240 { XML_NAMESPACE_DRAW
, XML_LINE
, XML_TOK_GROUP_LINE
},
241 { XML_NAMESPACE_DRAW
, XML_CIRCLE
, XML_TOK_GROUP_CIRCLE
},
242 { XML_NAMESPACE_DRAW
, XML_ELLIPSE
, XML_TOK_GROUP_ELLIPSE
},
243 { XML_NAMESPACE_DRAW
, XML_POLYGON
, XML_TOK_GROUP_POLYGON
},
244 { XML_NAMESPACE_DRAW
, XML_POLYLINE
, XML_TOK_GROUP_POLYLINE
},
245 { XML_NAMESPACE_DRAW
, XML_PATH
, XML_TOK_GROUP_PATH
},
247 { XML_NAMESPACE_DRAW
, XML_CONTROL
, XML_TOK_GROUP_CONTROL
},
248 { XML_NAMESPACE_DRAW
, XML_CONNECTOR
, XML_TOK_GROUP_CONNECTOR
},
249 { XML_NAMESPACE_DRAW
, XML_MEASURE
, XML_TOK_GROUP_MEASURE
},
250 { XML_NAMESPACE_DRAW
, XML_PAGE_THUMBNAIL
, XML_TOK_GROUP_PAGE
},
251 { XML_NAMESPACE_DRAW
, XML_CAPTION
, XML_TOK_GROUP_CAPTION
},
253 { XML_NAMESPACE_CHART
, XML_CHART
, XML_TOK_GROUP_CHART
},
254 { XML_NAMESPACE_DR3D
, XML_SCENE
, XML_TOK_GROUP_3DSCENE
},
256 { XML_NAMESPACE_DRAW
, XML_FRAME
, XML_TOK_GROUP_FRAME
},
257 { XML_NAMESPACE_DRAW
, XML_CUSTOM_SHAPE
, XML_TOK_GROUP_CUSTOM_SHAPE
},
259 { XML_NAMESPACE_DRAW
, XML_CUSTOM_SHAPE
, XML_TOK_GROUP_CUSTOM_SHAPE
},
260 { XML_NAMESPACE_OFFICE
, XML_ANNOTATION
, XML_TOK_GROUP_ANNOTATION
},
261 { XML_NAMESPACE_DRAW
, XML_A
, XML_TOK_GROUP_A
},
266 mpGroupShapeElemTokenMap
= new SvXMLTokenMap(aGroupShapeElemTokenMap
);
267 } // if(!mpGroupShapeElemTokenMap)
269 return *mpGroupShapeElemTokenMap
;
272 const SvXMLTokenMap
& XMLShapeImportHelper::GetFrameShapeElemTokenMap()
274 if(!mpFrameShapeElemTokenMap
)
276 static const SvXMLTokenMapEntry aFrameShapeElemTokenMap
[] =
278 { XML_NAMESPACE_DRAW
, XML_TEXT_BOX
, XML_TOK_FRAME_TEXT_BOX
},
279 { XML_NAMESPACE_DRAW
, XML_IMAGE
, XML_TOK_FRAME_IMAGE
},
280 { XML_NAMESPACE_DRAW
, XML_OBJECT
, XML_TOK_FRAME_OBJECT
},
281 { XML_NAMESPACE_DRAW
, XML_OBJECT_OLE
, XML_TOK_FRAME_OBJECT_OLE
},
282 { XML_NAMESPACE_DRAW
, XML_PLUGIN
, XML_TOK_FRAME_PLUGIN
},
283 { XML_NAMESPACE_DRAW
, XML_FLOATING_FRAME
, XML_TOK_FRAME_FLOATING_FRAME
},
284 { XML_NAMESPACE_DRAW
, XML_APPLET
, XML_TOK_FRAME_APPLET
},
285 { XML_NAMESPACE_TABLE
, XML_TABLE
, XML_TOK_FRAME_TABLE
},
289 mpFrameShapeElemTokenMap
= new SvXMLTokenMap(aFrameShapeElemTokenMap
);
290 } // if(!mpFrameShapeElemTokenMap)
292 return *mpFrameShapeElemTokenMap
;
295 const SvXMLTokenMap
& XMLShapeImportHelper::Get3DSceneShapeElemTokenMap()
297 if(!mp3DSceneShapeElemTokenMap
)
299 static const SvXMLTokenMapEntry a3DSceneShapeElemTokenMap
[] =
301 { XML_NAMESPACE_DR3D
, XML_SCENE
, XML_TOK_3DSCENE_3DSCENE
},
302 { XML_NAMESPACE_DR3D
, XML_CUBE
, XML_TOK_3DSCENE_3DCUBE
},
303 { XML_NAMESPACE_DR3D
, XML_SPHERE
, XML_TOK_3DSCENE_3DSPHERE
},
304 { XML_NAMESPACE_DR3D
, XML_ROTATE
, XML_TOK_3DSCENE_3DLATHE
},
305 { XML_NAMESPACE_DR3D
, XML_EXTRUDE
, XML_TOK_3DSCENE_3DEXTRUDE
},
309 mp3DSceneShapeElemTokenMap
= new SvXMLTokenMap(a3DSceneShapeElemTokenMap
);
310 } // if(!mp3DSceneShapeElemTokenMap)
312 return *mp3DSceneShapeElemTokenMap
;
315 const SvXMLTokenMap
& XMLShapeImportHelper::Get3DObjectAttrTokenMap()
317 if(!mp3DObjectAttrTokenMap
)
319 static const SvXMLTokenMapEntry a3DObjectAttrTokenMap
[] =
321 { XML_NAMESPACE_DRAW
, XML_STYLE_NAME
, XML_TOK_3DOBJECT_DRAWSTYLE_NAME
},
322 { XML_NAMESPACE_DR3D
, XML_TRANSFORM
, XML_TOK_3DOBJECT_TRANSFORM
},
326 mp3DObjectAttrTokenMap
= new SvXMLTokenMap(a3DObjectAttrTokenMap
);
327 } // if(!mp3DObjectAttrTokenMap)
329 return *mp3DObjectAttrTokenMap
;
332 const SvXMLTokenMap
& XMLShapeImportHelper::Get3DPolygonBasedAttrTokenMap()
334 if(!mp3DPolygonBasedAttrTokenMap
)
336 static const SvXMLTokenMapEntry a3DPolygonBasedAttrTokenMap
[] =
338 { XML_NAMESPACE_SVG
, XML_VIEWBOX
, XML_TOK_3DPOLYGONBASED_VIEWBOX
},
339 { XML_NAMESPACE_SVG
, XML_D
, XML_TOK_3DPOLYGONBASED_D
},
343 mp3DPolygonBasedAttrTokenMap
= new SvXMLTokenMap(a3DPolygonBasedAttrTokenMap
);
344 } // if(!mp3DPolygonBasedAttrTokenMap)
346 return *mp3DPolygonBasedAttrTokenMap
;
349 const SvXMLTokenMap
& XMLShapeImportHelper::Get3DCubeObjectAttrTokenMap()
351 if(!mp3DCubeObjectAttrTokenMap
)
353 static const SvXMLTokenMapEntry a3DCubeObjectAttrTokenMap
[] =
355 { XML_NAMESPACE_DR3D
, XML_MIN_EDGE
, XML_TOK_3DCUBEOBJ_MINEDGE
},
356 { XML_NAMESPACE_DR3D
, XML_MAX_EDGE
, XML_TOK_3DCUBEOBJ_MAXEDGE
},
360 mp3DCubeObjectAttrTokenMap
= new SvXMLTokenMap(a3DCubeObjectAttrTokenMap
);
361 } // if(!mp3DCubeObjectAttrTokenMap)
363 return *mp3DCubeObjectAttrTokenMap
;
366 const SvXMLTokenMap
& XMLShapeImportHelper::Get3DSphereObjectAttrTokenMap()
368 if(!mp3DSphereObjectAttrTokenMap
)
370 static const SvXMLTokenMapEntry a3DSphereObjectAttrTokenMap
[] =
372 { XML_NAMESPACE_DR3D
, XML_CENTER
, XML_TOK_3DSPHEREOBJ_CENTER
},
373 { XML_NAMESPACE_DR3D
, XML_SIZE
, XML_TOK_3DSPHEREOBJ_SIZE
},
377 mp3DSphereObjectAttrTokenMap
= new SvXMLTokenMap(a3DSphereObjectAttrTokenMap
);
378 } // if(!mp3DSphereObjectAttrTokenMap)
380 return *mp3DSphereObjectAttrTokenMap
;
383 const SvXMLTokenMap
& XMLShapeImportHelper::Get3DLightAttrTokenMap()
385 if(!mp3DLightAttrTokenMap
)
387 static const SvXMLTokenMapEntry a3DLightAttrTokenMap
[] =
389 { XML_NAMESPACE_DR3D
, XML_DIFFUSE_COLOR
, XML_TOK_3DLIGHT_DIFFUSE_COLOR
},
390 { XML_NAMESPACE_DR3D
, XML_DIRECTION
, XML_TOK_3DLIGHT_DIRECTION
},
391 { XML_NAMESPACE_DR3D
, XML_ENABLED
, XML_TOK_3DLIGHT_ENABLED
},
392 { XML_NAMESPACE_DR3D
, XML_SPECULAR
, XML_TOK_3DLIGHT_SPECULAR
},
396 mp3DLightAttrTokenMap
= new SvXMLTokenMap(a3DLightAttrTokenMap
);
397 } // if(!mp3DLightAttrTokenMap)
399 return *mp3DLightAttrTokenMap
;
402 SvXMLShapeContext
* XMLShapeImportHelper::Create3DSceneChildContext(
403 SvXMLImport
& rImport
,
404 sal_uInt16 p_nPrefix
,
405 const OUString
& rLocalName
,
406 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
,
407 uno::Reference
< drawing::XShapes
>& rShapes
)
409 SdXMLShapeContext
*pContext
= 0L;
413 const SvXMLTokenMap
& rTokenMap
= Get3DSceneShapeElemTokenMap();
414 switch(rTokenMap
.Get(p_nPrefix
, rLocalName
))
416 case XML_TOK_3DSCENE_3DSCENE
:
418 // dr3d:3dscene inside dr3d:3dscene context
419 pContext
= new SdXML3DSceneShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false);
422 case XML_TOK_3DSCENE_3DCUBE
:
424 // dr3d:3dcube inside dr3d:3dscene context
425 pContext
= new SdXML3DCubeObjectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false);
428 case XML_TOK_3DSCENE_3DSPHERE
:
430 // dr3d:3dsphere inside dr3d:3dscene context
431 pContext
= new SdXML3DSphereObjectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false);
434 case XML_TOK_3DSCENE_3DLATHE
:
436 // dr3d:3dlathe inside dr3d:3dscene context
437 pContext
= new SdXML3DLatheObjectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false);
440 case XML_TOK_3DSCENE_3DEXTRUDE
:
442 // dr3d:3dextrude inside dr3d:3dscene context
443 pContext
= new SdXML3DExtrudeObjectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false);
449 // now parse the attribute list and call the child context for each unknown attribute
450 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
451 for(sal_Int16
a(0); a
< nAttrCount
; a
++)
453 const OUString
& rAttrName
= xAttrList
->getNameByIndex(a
);
455 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().GetKeyByAttrName(rAttrName
, &aLocalName
);
456 const OUString
aValue( xAttrList
->getValueByIndex(a
) );
458 pContext
->processAttribute( nPrefix
, aLocalName
, aValue
);
464 void XMLShapeImportHelper::SetStylesContext(SvXMLStylesContext
* pNew
)
466 mpStylesContext
= pNew
;
468 mpStylesContext
->AddFirstRef();
471 void XMLShapeImportHelper::SetAutoStylesContext(SvXMLStylesContext
* pNew
)
473 mpAutoStylesContext
= pNew
;
474 if (mpAutoStylesContext
)
475 mpAutoStylesContext
->AddFirstRef();
478 SvXMLShapeContext
* XMLShapeImportHelper::CreateGroupChildContext(
479 SvXMLImport
& rImport
,
480 sal_uInt16 p_nPrefix
,
481 const OUString
& rLocalName
,
482 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
,
483 uno::Reference
< drawing::XShapes
>& rShapes
,
484 bool bTemporaryShape
)
486 SdXMLShapeContext
*pContext
= 0L;
488 const SvXMLTokenMap
& rTokenMap
= GetGroupShapeElemTokenMap();
489 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
491 switch(rTokenMap
.Get(p_nPrefix
, rLocalName
))
493 case XML_TOK_GROUP_GROUP
:
495 // draw:g inside group context (RECURSIVE)
496 pContext
= new SdXMLGroupShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
499 case XML_TOK_GROUP_3DSCENE
:
501 // dr3d:3dscene inside group context
502 pContext
= new SdXML3DSceneShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
505 case XML_TOK_GROUP_RECT
:
507 // draw:rect inside group context
508 pContext
= new SdXMLRectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
511 case XML_TOK_GROUP_LINE
:
513 // draw:line inside group context
514 pContext
= new SdXMLLineShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
517 case XML_TOK_GROUP_CIRCLE
:
518 case XML_TOK_GROUP_ELLIPSE
:
520 // draw:circle or draw:ellipse inside group context
521 pContext
= new SdXMLEllipseShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
524 case XML_TOK_GROUP_POLYGON
:
525 case XML_TOK_GROUP_POLYLINE
:
527 // draw:polygon or draw:polyline inside group context
528 pContext
= new SdXMLPolygonShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
,
529 rTokenMap
.Get(p_nPrefix
, rLocalName
) == XML_TOK_GROUP_POLYGON
, bTemporaryShape
);
532 case XML_TOK_GROUP_PATH
:
534 // draw:path inside group context
535 pContext
= new SdXMLPathShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
538 case XML_TOK_GROUP_FRAME
:
540 // text:text-box inside group context
541 pContext
= new SdXMLFrameShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
544 case XML_TOK_GROUP_CONTROL
:
546 // draw:control inside group context
547 pContext
= new SdXMLControlShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
550 case XML_TOK_GROUP_CONNECTOR
:
552 // draw:connector inside group context
553 pContext
= new SdXMLConnectorShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
556 case XML_TOK_GROUP_MEASURE
:
558 // draw:measure inside group context
559 pContext
= new SdXMLMeasureShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
562 case XML_TOK_GROUP_PAGE
:
564 // draw:page inside group context
565 pContext
= new SdXMLPageShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
568 case XML_TOK_GROUP_CAPTION
:
569 case XML_TOK_GROUP_ANNOTATION
:
571 // draw:caption inside group context
572 pContext
= new SdXMLCaptionShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
575 case XML_TOK_GROUP_CHART
:
577 // chart:chart inside group context
578 pContext
= new SdXMLChartShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
581 case XML_TOK_GROUP_CUSTOM_SHAPE
:
584 pContext
= new SdXMLCustomShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false );
587 case XML_TOK_GROUP_A
:
589 return new SdXMLShapeLinkContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
);
591 // add other shapes here...
593 return new SvXMLShapeContext( rImport
, p_nPrefix
, rLocalName
, bTemporaryShape
);
596 // now parse the attribute list and call the child context for each unknown attribute
597 for(sal_Int16
a(0); a
< nAttrCount
; a
++)
599 const OUString
& rAttrName
= xAttrList
->getNameByIndex(a
);
601 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().GetKeyByAttrName(rAttrName
, &aLocalName
);
602 const OUString
aValue( xAttrList
->getValueByIndex(a
) );
604 pContext
->processAttribute( nPrefix
, aLocalName
, aValue
);
610 // This method is called from SdXMLFrameShapeContext to create children of drawe:frame
611 SvXMLShapeContext
* XMLShapeImportHelper::CreateFrameChildContext(
612 SvXMLImport
& rImport
,
613 sal_uInt16 p_nPrefix
,
614 const OUString
& rLocalName
,
615 const uno::Reference
< xml::sax::XAttributeList
>& rAttrList
,
616 uno::Reference
< drawing::XShapes
>& rShapes
,
617 const uno::Reference
< xml::sax::XAttributeList
>& rFrameAttrList
)
619 SdXMLShapeContext
*pContext
= 0L;
621 const SvXMLTokenMap
& rTokenMap
= GetFrameShapeElemTokenMap();
623 SvXMLAttributeList
*pAttrList
= new SvXMLAttributeList( rAttrList
);
624 if( rFrameAttrList
.is() )
625 pAttrList
->AppendAttributeList( rFrameAttrList
);
626 uno::Reference
< xml::sax::XAttributeList
> xAttrList
= pAttrList
;
628 switch(rTokenMap
.Get(p_nPrefix
, rLocalName
))
630 case XML_TOK_FRAME_TEXT_BOX
:
632 // text:text-box inside group context
633 pContext
= new SdXMLTextBoxShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false );
636 case XML_TOK_FRAME_IMAGE
:
638 // office:image inside group context
639 pContext
= new SdXMLGraphicObjectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false );
642 case XML_TOK_FRAME_OBJECT
:
643 case XML_TOK_FRAME_OBJECT_OLE
:
645 // draw:object or draw:object_ole
646 pContext
= new SdXMLObjectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false );
649 case XML_TOK_FRAME_TABLE
:
651 // draw:object or draw:object_ole
652 if( rImport
.IsTableShapeSupported() )
653 pContext
= new SdXMLTableShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
);
657 case XML_TOK_FRAME_PLUGIN
:
660 pContext
= new SdXMLPluginShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false );
663 case XML_TOK_FRAME_FLOATING_FRAME
:
665 // draw:floating-frame
666 pContext
= new SdXMLFloatingFrameShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false );
669 case XML_TOK_FRAME_APPLET
:
672 pContext
= new SdXMLAppletShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, false );
675 // add other shapes here...
682 // now parse the attribute list and call the child context for each unknown attribute
683 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
684 for(sal_Int16
a(0); a
< nAttrCount
; a
++)
686 const OUString
& rAttrName
= xAttrList
->getNameByIndex(a
);
688 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().GetKeyByAttrName(rAttrName
, &aLocalName
);
689 const OUString
aValue( xAttrList
->getValueByIndex(a
) );
691 pContext
->processAttribute( nPrefix
, aLocalName
, aValue
);
698 SvXMLImportContext
*XMLShapeImportHelper::CreateFrameChildContext(
699 SvXMLImportContext
*pThisContext
,
701 const OUString
& rLocalName
,
702 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
704 SvXMLImportContext
* pContext
= NULL
;
706 SdXMLFrameShapeContext
*pFrameContext
= PTR_CAST( SdXMLFrameShapeContext
, pThisContext
);
708 pContext
= pFrameContext
->CreateChildContext( nPrefix
, rLocalName
, xAttrList
);
713 /** this function is called whenever the implementation classes like to add this new
714 shape to the given XShapes.
716 void XMLShapeImportHelper::addShape( uno::Reference
< drawing::XShape
>& rShape
,
717 const uno::Reference
< xml::sax::XAttributeList
>&,
718 uno::Reference
< drawing::XShapes
>& rShapes
)
720 if( rShape
.is() && rShapes
.is() )
722 // add new shape to parent
723 rShapes
->add( rShape
);
727 /** this function is called whenever the implementation classes have finished importing
728 a shape to the given XShapes. The shape is already inserted into its XShapes and
729 all properties and styles are set.
731 void XMLShapeImportHelper::finishShape(
732 com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>& rShape
,
733 const com::sun::star::uno::Reference
< com::sun::star::xml::sax::XAttributeList
>&,
734 com::sun::star::uno::Reference
< com::sun::star::drawing::XShapes
>&)
736 /* Set property <PositionLayoutDir>
737 to <PositionInHoriL2R>, if it exists and the import states that
738 the shape positioning attributes are in horizontal left-to-right
739 layout. This is the case for the OpenOffice.org file format.
740 This setting is done for Writer documents, because the property
741 only exists at service com::sun::star::text::Shape - the Writer
742 UNO service for shapes.
743 The value indicates that the positioning attributes are given
744 in horizontal left-to-right layout. The property is evaluated
745 during the first positioning of the shape in order to convert
746 the shape position given in the OpenOffice.org file format to
747 the one for the OASIS Open Office file format. (#i28749#, #i36248#)
749 uno::Reference
< beans::XPropertySet
> xPropSet(rShape
, uno::UNO_QUERY
);
752 if ( mrImporter
.IsShapePositionInHoriL2R() &&
753 xPropSet
->getPropertySetInfo()->hasPropertyByName(
754 OUString("PositionLayoutDir")) )
756 uno::Any aPosLayoutDir
;
757 aPosLayoutDir
<<= text::PositionLayoutDir::PositionInHoriL2R
;
758 xPropSet
->setPropertyValue(
759 OUString("PositionLayoutDir"),
765 // helper functions for z-order sorting
771 bool operator<(const ZOrderHint
& rComp
) const { return nShould
< rComp
.nShould
; }
774 class ShapeSortContext
777 uno::Reference
< drawing::XShapes
> mxShapes
;
778 list
<ZOrderHint
> maZOrderList
;
779 list
<ZOrderHint
> maUnsortedList
;
781 sal_Int32 mnCurrentZ
;
782 ShapeSortContext
* mpParentContext
;
783 const OUString msZOrder
;
785 ShapeSortContext( uno::Reference
< drawing::XShapes
>& rShapes
, ShapeSortContext
* pParentContext
= NULL
);
787 void moveShape( sal_Int32 nSourcePos
, sal_Int32 nDestPos
);
790 ShapeSortContext::ShapeSortContext( uno::Reference
< drawing::XShapes
>& rShapes
, ShapeSortContext
* pParentContext
)
791 : mxShapes( rShapes
), mnCurrentZ( 0 ), mpParentContext( pParentContext
),
796 void ShapeSortContext::moveShape( sal_Int32 nSourcePos
, sal_Int32 nDestPos
)
798 uno::Any
aAny( mxShapes
->getByIndex( nSourcePos
) );
799 uno::Reference
< beans::XPropertySet
> xPropSet
;
802 if( xPropSet
.is() && xPropSet
->getPropertySetInfo()->hasPropertyByName( msZOrder
) )
805 xPropSet
->setPropertyValue( msZOrder
, aAny
);
807 list
<ZOrderHint
>::iterator aIter
= maZOrderList
.begin();
808 list
<ZOrderHint
>::iterator aEnd
= maZOrderList
.end();
810 while( aIter
!= aEnd
)
812 if( (*aIter
).nIs
< nSourcePos
)
814 DBG_ASSERT( (*aIter
).nIs
>= nDestPos
, "Shape sorting failed" );
820 aIter
= maUnsortedList
.begin();
821 aEnd
= maUnsortedList
.end();
823 while( aIter
!= aEnd
)
825 if( (*aIter
).nIs
< nSourcePos
)
827 DBG_ASSERT( (*aIter
).nIs
>= nDestPos
, "shape sorting failed" );
835 void XMLShapeImportHelper::pushGroupForSorting( uno::Reference
< drawing::XShapes
>& rShapes
)
837 mpImpl
->mpSortContext
= new ShapeSortContext( rShapes
, mpImpl
->mpSortContext
);
840 void XMLShapeImportHelper::popGroupAndSort()
842 DBG_ASSERT( mpImpl
->mpSortContext
, "No context to sort!" );
843 if( mpImpl
->mpSortContext
== NULL
)
848 list
<ZOrderHint
>& rZList
= mpImpl
->mpSortContext
->maZOrderList
;
849 list
<ZOrderHint
>& rUnsortedList
= mpImpl
->mpSortContext
->maUnsortedList
;
852 if( !rZList
.empty() )
854 // only do something if we have shapes to sort
856 // check if there are more shapes than inserted with ::shapeWithZIndexAdded()
857 // This can happen if there where already shapes on the page before import
858 // Since the writer may delete some of this shapes during import, we need
859 // to do this here and not in our c'tor anymore
861 // check if we have more shapes than we know of
862 sal_Int32 nCount
= mpImpl
->mpSortContext
->mxShapes
->getCount();
864 nCount
-= rZList
.size();
865 nCount
-= rUnsortedList
.size();
869 // first update offsets of added shapes
870 list
<ZOrderHint
>::iterator
aIter( rZList
.begin() );
871 while( aIter
!= rZList
.end() )
872 (*aIter
++).nIs
+= nCount
;
874 aIter
= rUnsortedList
.begin();
875 while( aIter
!= rUnsortedList
.end() )
876 (*aIter
++).nIs
+= nCount
;
878 // second add the already existing shapes in the unsorted list
885 aNewHint
.nIs
= nCount
;
886 aNewHint
.nShould
= -1;
888 rUnsortedList
.insert(rUnsortedList
.begin(), aNewHint
);
893 // sort z ordered shapes
896 // this is the current index, all shapes before that
897 // index are finished
898 sal_Int32 nIndex
= 0;
899 while( !rZList
.empty() )
901 list
<ZOrderHint
>::iterator
aIter( rZList
.begin() );
903 while( nIndex
< (*aIter
).nShould
&& !rUnsortedList
.empty() )
905 ZOrderHint
aGapHint( *rUnsortedList
.begin() );
906 rUnsortedList
.pop_front();
908 mpImpl
->mpSortContext
->moveShape( aGapHint
.nIs
, nIndex
++ );
911 if( (*aIter
).nIs
!= nIndex
)
912 mpImpl
->mpSortContext
->moveShape( (*aIter
).nIs
, nIndex
);
919 catch( uno::Exception
& )
921 OSL_FAIL("exception while sorting shapes, sorting failed!");
924 // put parent on top and delete current context, were done
925 ShapeSortContext
* pContext
= mpImpl
->mpSortContext
;
926 mpImpl
->mpSortContext
= pContext
->mpParentContext
;
930 void XMLShapeImportHelper::shapeWithZIndexAdded( com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>&, sal_Int32 nZIndex
)
932 if( mpImpl
->mpSortContext
)
935 aNewHint
.nIs
= mpImpl
->mpSortContext
->mnCurrentZ
++;
936 aNewHint
.nShould
= nZIndex
;
940 // don't care, so add to unsorted list
941 mpImpl
->mpSortContext
->maUnsortedList
.push_back(aNewHint
);
945 // insert into sort list
946 mpImpl
->mpSortContext
->maZOrderList
.push_back(aNewHint
);
951 void XMLShapeImportHelper::addShapeConnection( com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>& rConnectorShape
,
953 const OUString
& rDestShapeId
,
954 sal_Int32 nDestGlueId
)
956 ConnectionHint aHint
;
957 aHint
.mxConnector
= rConnectorShape
;
958 aHint
.bStart
= bStart
;
959 aHint
.aDestShapeId
= rDestShapeId
;
960 aHint
.nDestGlueId
= nDestGlueId
;
962 mpImpl
->maConnections
.push_back( aHint
);
965 void XMLShapeImportHelper::restoreConnections()
967 if( !mpImpl
->maConnections
.empty() )
971 const vector
<ConnectionHint
>::size_type nCount
= mpImpl
->maConnections
.size();
972 for( vector
<ConnectionHint
>::size_type i
= 0; i
< nCount
; i
++ )
974 ConnectionHint
& rHint
= mpImpl
->maConnections
[i
];
975 uno::Reference
< beans::XPropertySet
> xConnector( rHint
.mxConnector
, uno::UNO_QUERY
);
976 if( xConnector
.is() )
978 // #86637# remember line deltas
979 uno::Any aLine1Delta
;
980 uno::Any aLine2Delta
;
981 uno::Any aLine3Delta
;
982 OUString
aStr1("EdgeLine1Delta");
983 OUString
aStr2("EdgeLine2Delta");
984 OUString
aStr3("EdgeLine3Delta");
985 aLine1Delta
= xConnector
->getPropertyValue(aStr1
);
986 aLine2Delta
= xConnector
->getPropertyValue(aStr2
);
987 aLine3Delta
= xConnector
->getPropertyValue(aStr3
);
989 // #86637# simply setting these values WILL force the connector to do
990 // an new layout promptly. So the line delta values have to be rescued
991 // and restored around connector changes.
992 uno::Reference
< drawing::XShape
> xShape(
993 mrImporter
.getInterfaceToIdentifierMapper().getReference( rHint
.aDestShapeId
), uno::UNO_QUERY
);
997 xConnector
->setPropertyValue( rHint
.bStart
? msStartShape
: msEndShape
, aAny
);
999 sal_Int32 nGlueId
= rHint
.nDestGlueId
< 4 ? rHint
.nDestGlueId
: getGluePointId( xShape
, rHint
.nDestGlueId
);
1001 xConnector
->setPropertyValue( rHint
.bStart
? msStartGluePointIndex
: msEndGluePointIndex
, aAny
);
1004 // #86637# restore line deltas
1005 xConnector
->setPropertyValue(aStr1
, aLine1Delta
);
1006 xConnector
->setPropertyValue(aStr2
, aLine2Delta
);
1007 xConnector
->setPropertyValue(aStr3
, aLine3Delta
);
1010 mpImpl
->maConnections
.clear();
1014 SvXMLImportPropertyMapper
* XMLShapeImportHelper::CreateShapePropMapper( const uno::Reference
< frame::XModel
>& rModel
, SvXMLImport
& rImport
)
1016 rtl::Reference
< XMLPropertyHandlerFactory
> xFactory
= new XMLSdPropHdlFactory( rModel
, rImport
);
1017 rtl::Reference
< XMLPropertySetMapper
> xMapper
= new XMLShapePropertySetMapper( xFactory
, false );
1018 SvXMLImportPropertyMapper
* pResult
= new SvXMLImportPropertyMapper( xMapper
, rImport
);
1020 // chain text attributes
1021 pResult
->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport
) );
1025 /** adds a mapping for a glue point identifier from an xml file to the identifier created after inserting
1026 the new glue point into the core. The saved mappings can be retrieved by getGluePointId() */
1027 void XMLShapeImportHelper::addGluePointMapping( com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>& xShape
,
1028 sal_Int32 nSourceId
, sal_Int32 nDestinnationId
)
1031 mpPageContext
->maShapeGluePointsMap
[xShape
][nSourceId
] = nDestinnationId
;
1034 /** find mapping for given DestinationID. This allows to extract the original draw:id imported with a draw:glue-point */
1035 sal_Int32
XMLShapeImportHelper::findGluePointMapping(
1036 const com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>& xShape
,
1037 sal_Int32 nDestinnationId
) const
1041 ShapeGluePointsMap::iterator
aShapeIter( mpPageContext
->maShapeGluePointsMap
.find( xShape
) );
1043 if( aShapeIter
!= mpPageContext
->maShapeGluePointsMap
.end() )
1045 GluePointIdMap::iterator aShapeIdIter
= (*aShapeIter
).second
.begin();
1046 GluePointIdMap::iterator aShapeIdEnd
= (*aShapeIter
).second
.end();
1048 while ( aShapeIdIter
!= aShapeIdEnd
)
1050 if ( (*aShapeIdIter
).second
== nDestinnationId
)
1052 return (*aShapeIdIter
).first
;
1063 /** moves all current DestinationId's by n */
1064 void XMLShapeImportHelper::moveGluePointMapping( const com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>& xShape
, const sal_Int32 n
)
1068 ShapeGluePointsMap::iterator
aShapeIter( mpPageContext
->maShapeGluePointsMap
.find( xShape
) );
1069 if( aShapeIter
!= mpPageContext
->maShapeGluePointsMap
.end() )
1071 GluePointIdMap::iterator aShapeIdIter
= (*aShapeIter
).second
.begin();
1072 GluePointIdMap::iterator aShapeIdEnd
= (*aShapeIter
).second
.end();
1073 while ( aShapeIdIter
!= aShapeIdEnd
)
1075 if ( (*aShapeIdIter
).second
!= -1 )
1076 (*aShapeIdIter
).second
+= n
;
1083 /** retrieves a mapping for a glue point identifier from the current xml file to the identifier created after
1084 inserting the new glue point into the core. The mapping must be initialized first with addGluePointMapping() */
1085 sal_Int32
XMLShapeImportHelper::getGluePointId( const com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>& xShape
, sal_Int32 nSourceId
)
1089 ShapeGluePointsMap::iterator
aShapeIter( mpPageContext
->maShapeGluePointsMap
.find( xShape
) );
1090 if( aShapeIter
!= mpPageContext
->maShapeGluePointsMap
.end() )
1092 GluePointIdMap::iterator aIdIter
= (*aShapeIter
).second
.find(nSourceId
);
1093 if( aIdIter
!= (*aShapeIter
).second
.end() )
1094 return (*aIdIter
).second
;
1101 /** this method must be calling before the first shape is imported for the given page */
1102 void XMLShapeImportHelper::startPage( com::sun::star::uno::Reference
< com::sun::star::drawing::XShapes
>& rShapes
)
1104 XMLShapeImportPageContextImpl
* pOldContext
= mpPageContext
;
1105 mpPageContext
= new XMLShapeImportPageContextImpl();
1106 mpPageContext
->mpNext
= pOldContext
;
1107 mpPageContext
->mxShapes
= rShapes
;
1110 /** this method must be calling after the last shape is imported for the given page */
1111 void XMLShapeImportHelper::endPage( com::sun::star::uno::Reference
< com::sun::star::drawing::XShapes
>&
1117 DBG_ASSERT( mpPageContext
&& (mpPageContext
->mxShapes
== rShapes
), "wrong call to endPage(), no startPage called or wrong page" );
1118 if( NULL
== mpPageContext
)
1121 restoreConnections();
1123 XMLShapeImportPageContextImpl
* pNextContext
= mpPageContext
->mpNext
;
1124 delete mpPageContext
;
1125 mpPageContext
= pNextContext
;
1129 /** defines if the import should increment the progress bar or not */
1130 void XMLShapeImportHelper::enableHandleProgressBar( bool bEnable
)
1132 mpImpl
->mbHandleProgressBar
= bEnable
;
1135 bool XMLShapeImportHelper::IsHandleProgressBarEnabled() const
1137 return mpImpl
->mbHandleProgressBar
;
1140 /** queries the capability of the current model to create presentation shapes */
1141 bool XMLShapeImportHelper::IsPresentationShapesSupported()
1143 return mpImpl
->mbIsPresentationShapesSupported
;
1146 const rtl::Reference
< XMLTableImport
>& XMLShapeImportHelper::GetShapeTableImport()
1148 if( !mxShapeTableImport
.is() )
1150 rtl::Reference
< XMLPropertyHandlerFactory
> xFactory( new XMLSdPropHdlFactory( mrImporter
.GetModel(), mrImporter
) );
1151 rtl::Reference
< XMLPropertySetMapper
> xPropertySetMapper( new XMLShapePropertySetMapper( xFactory
.get(), false ) );
1152 mxShapeTableImport
= new XMLTableImport( mrImporter
, xPropertySetMapper
, xFactory
);
1155 return mxShapeTableImport
;
1158 void SvXMLShapeContext::setHyperlink( const OUString
& rHyperlink
)
1160 msHyperlink
= rHyperlink
;
1163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */