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 .
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>
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 ::rtl::OUString
;
47 using ::rtl::OUStringBuffer
;
49 using namespace ::std
;
50 using namespace ::com::sun::star
;
51 using namespace ::xmloff::token
;
53 //////////////////////////////////////////////////////////////////////////////
57 bool operator()(const sal_Int32 p
, sal_Int32 q
) const
63 typedef std::map
<sal_Int32
,com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>,ltint32
> IdShapeMap
;
67 com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> mxConnector
;
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
),
125 mpPropertySetMapper(0L),
126 mpPresPagePropsMapper(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();
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?
231 mpStylesContext
->Clear();
232 mpStylesContext
->ReleaseRef();
235 if(mpAutoStylesContext
)
237 mpAutoStylesContext
->Clear();
238 mpAutoStylesContext
->ReleaseRef();
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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
},
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;
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
);
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
);
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
);
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
);
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
);
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
);
491 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().GetKeyByAttrName(rAttrName
, &aLocalName
);
492 const OUString
aValue( xAttrList
->getValueByIndex(a
) );
494 pContext
->processAttribute( nPrefix
, aLocalName
, aValue
);
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
);
539 case XML_TOK_GROUP_3DSCENE
:
541 // dr3d:3dscene inside group context
542 pContext
= new SdXML3DSceneShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
545 case XML_TOK_GROUP_RECT
:
547 // draw:rect inside group context
548 pContext
= new SdXMLRectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
551 case XML_TOK_GROUP_LINE
:
553 // draw:line inside group context
554 pContext
= new SdXMLLineShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
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
);
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
);
572 case XML_TOK_GROUP_PATH
:
574 // draw:path inside group context
575 pContext
= new SdXMLPathShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
578 case XML_TOK_GROUP_FRAME
:
580 // text:text-box inside group context
581 pContext
= new SdXMLFrameShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
584 case XML_TOK_GROUP_CONTROL
:
586 // draw:control inside group context
587 pContext
= new SdXMLControlShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
590 case XML_TOK_GROUP_CONNECTOR
:
592 // draw:connector inside group context
593 pContext
= new SdXMLConnectorShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
596 case XML_TOK_GROUP_MEASURE
:
598 // draw:measure inside group context
599 pContext
= new SdXMLMeasureShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
602 case XML_TOK_GROUP_PAGE
:
604 // draw:page inside group context
605 pContext
= new SdXMLPageShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
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
);
615 case XML_TOK_GROUP_CHART
:
617 // chart:chart inside group context
618 pContext
= new SdXMLChartShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, bTemporaryShape
);
621 case XML_TOK_GROUP_CUSTOM_SHAPE
:
624 pContext
= new SdXMLCustomShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, sal_False
);
627 case XML_TOK_GROUP_A
:
629 return new SdXMLShapeLinkContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
);
631 // add other shapes here...
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
);
641 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().GetKeyByAttrName(rAttrName
, &aLocalName
);
642 const OUString
aValue( xAttrList
->getValueByIndex(a
) );
644 pContext
->processAttribute( nPrefix
, aLocalName
, aValue
);
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
);
677 case XML_TOK_FRAME_IMAGE
:
679 // office:image inside group context
680 pContext
= new SdXMLGraphicObjectShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, sal_False
);
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
);
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
);
698 case XML_TOK_FRAME_PLUGIN
:
701 pContext
= new SdXMLPluginShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, sal_False
);
704 case XML_TOK_FRAME_FLOATING_FRAME
:
706 // draw:floating-frame
707 pContext
= new SdXMLFloatingFrameShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, sal_False
);
710 case XML_TOK_FRAME_APPLET
:
713 pContext
= new SdXMLAppletShapeContext( rImport
, p_nPrefix
, rLocalName
, xAttrList
, rShapes
, sal_False
);
716 // add other shapes here...
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
);
729 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().GetKeyByAttrName(rAttrName
, &aLocalName
);
730 const OUString
aValue( xAttrList
->getValueByIndex(a
) );
732 pContext
->processAttribute( nPrefix
, aLocalName
, aValue
);
739 SvXMLImportContext
*XMLShapeImportHelper::CreateFrameChildContext(
740 SvXMLImportContext
*pThisContext
,
742 const OUString
& rLocalName
,
743 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
745 SvXMLImportContext
* pContext
= NULL
;
747 SdXMLFrameShapeContext
*pFrameContext
= PTR_CAST( SdXMLFrameShapeContext
, pThisContext
);
749 pContext
= pFrameContext
->CreateChildContext( nPrefix
, rLocalName
, xAttrList
);
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
);
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")),
807 // helper functions for z-order sorting
813 int operator<(const ZOrderHint
& rComp
) const { return nShould
< rComp
.nShould
; }
816 class ShapeSortContext
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
;
844 if( xPropSet
.is() && xPropSet
->getPropertySetInfo()->hasPropertyByName( msZOrder
) )
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" );
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" );
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
)
890 list
<ZOrderHint
>& rZList
= mpImpl
->mpSortContext
->maZOrderList
;
891 list
<ZOrderHint
>& rUnsortedList
= mpImpl
->mpSortContext
->maUnsortedList
;
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();
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
928 aNewHint
.nIs
= nCount
;
929 aNewHint
.nShould
= -1;
931 rUnsortedList
.insert(rUnsortedList
.begin(), aNewHint
);
936 // sort z ordered shapes
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
);
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
;
973 void XMLShapeImportHelper::shapeWithZIndexAdded( com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
>&, sal_Int32 nZIndex
)
975 if( mpImpl
->mpSortContext
)
978 aNewHint
.nIs
= mpImpl
->mpSortContext
->mnCurrentZ
++;
979 aNewHint
.nShould
= nZIndex
;
983 // don't care, so add to unsorted list
984 mpImpl
->mpSortContext
->maUnsortedList
.push_back(aNewHint
);
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
,
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() )
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
);
1040 xConnector
->setPropertyValue( rHint
.bStart
? msStartShape
: msEndShape
, aAny
);
1042 sal_Int32 nGlueId
= rHint
.nDestGlueId
< 4 ? rHint
.nDestGlueId
: getGluePointId( xShape
, rHint
.nDestGlueId
);
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
) );
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
)
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
)
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
;
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
)
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
;
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
>&
1131 DBG_ASSERT( mpPageContext
&& (mpPageContext
->mxShapes
== rShapes
), "wrong call to endPage(), no startPage called or wrong page" );
1132 if( NULL
== mpPageContext
)
1135 restoreConnections();
1137 XMLShapeImportPageContextImpl
* pNextContext
= mpPageContext
->mpNext
;
1138 delete mpPageContext
;
1139 mpPageContext
= pNextContext
;
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: */