xref: /trunk/main/xmloff/source/draw/shapeimport.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include <tools/debug.hxx>
32 
33 #include <com/sun/star/text/PositionLayoutDir.hpp>
34 #include <com/sun/star/chart/XChartDocument.hpp>
35 
36 #include "unointerfacetouniqueidentifiermapper.hxx"
37 
38 #include <list>
39 
40 #ifndef _XMLOFF_SHAPEIMPORT_HXX
41 #include <xmloff/shapeimport.hxx>
42 #endif
43 #include <xmloff/xmltkmap.hxx>
44 #include "xmloff/xmlnmspe.hxx"
45 #include <xmloff/xmltoken.hxx>
46 #include "ximpstyl.hxx"
47 #include "ximpshap.hxx"
48 #include "sdpropls.hxx"
49 #include <xmloff/xmlprmap.hxx>
50 #include "ximp3dscene.hxx"
51 #include "ximp3dobject.hxx"
52 #include "ximpgrp.hxx"
53 #include "ximplink.hxx"
54 
55 #include <map>
56 #include <vector>
57 
58 using ::rtl::OUString;
59 using ::rtl::OUStringBuffer;
60 
61 using namespace ::std;
62 using namespace ::com::sun::star;
63 using namespace ::xmloff::token;
64 
65 //////////////////////////////////////////////////////////////////////////////
66 
67 struct ltint32
68 {
69   bool operator()(const sal_Int32 p, sal_Int32 q) const
70   {
71     return p < q;
72   }
73 };
74 
75 typedef std::map<sal_Int32,com::sun::star::uno::Reference< com::sun::star::drawing::XShape >,ltint32> IdShapeMap;
76 
77 struct ConnectionHint
78 {
79     com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxConnector;
80     sal_Bool  bStart;
81     OUString aDestShapeId;
82     sal_Int32 nDestGlueId;
83 };
84 
85 struct XShapeCompareHelper
86 {
87   bool operator()(com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x1,
88                   com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x2 ) const
89   {
90     return x1.get() < x2.get();
91   }
92 };
93 
94 /** this map store all glue point id mappings for shapes that had user defined glue points. This
95     is needed because on insertion the glue points will get a new and unique id */
96 typedef std::map<sal_Int32,sal_Int32,ltint32> GluePointIdMap;
97 typedef std::map< com::sun::star::uno::Reference < com::sun::star::drawing::XShape >, GluePointIdMap, XShapeCompareHelper > ShapeGluePointsMap;
98 
99 /** this struct is created for each startPage() call and stores information that is needed during
100     import of shapes for one page. Since pages could be nested ( notes pages inside impress ) there
101     is a pointer so one can build up a stack of this structs */
102 struct XMLShapeImportPageContextImpl
103 {
104     ShapeGluePointsMap      maShapeGluePointsMap;
105 
106     uno::Reference < drawing::XShapes > mxShapes;
107 
108     struct XMLShapeImportPageContextImpl* mpNext;
109 };
110 
111 /** this class is to enable adding members to the XMLShapeImportHelper without getting incompatible */
112 struct XMLShapeImportHelperImpl
113 {
114     // context for sorting shapes
115     ShapeSortContext*           mpSortContext;
116 
117     IdShapeMap                  maShapeIds;
118 
119     std::vector<ConnectionHint> maConnections;
120 
121     // #88546# possibility to swich progress bar handling on/off
122     sal_Bool                    mbHandleProgressBar;
123 
124     // stores the capability of the current model to create presentation shapes
125     sal_Bool                    mbIsPresentationShapesSupported;
126 };
127 
128 //////////////////////////////////////////////////////////////////////////////
129 
130 XMLShapeImportHelper::XMLShapeImportHelper(
131         SvXMLImport& rImporter,
132         const uno::Reference< frame::XModel>& rModel,
133         SvXMLImportPropertyMapper *pExtMapper )
134 :   mpPageContext(NULL),
135     mxModel(rModel),
136 
137     mpPropertySetMapper(0L),
138     mpPresPagePropsMapper(0L),
139     mpStylesContext(0L),
140     mpAutoStylesContext(0L),
141     mpGroupShapeElemTokenMap(0L),
142     mpFrameShapeElemTokenMap(0L),
143     mp3DSceneShapeElemTokenMap(0L),
144     mp3DObjectAttrTokenMap(0L),
145     mp3DPolygonBasedAttrTokenMap(0L),
146     mp3DCubeObjectAttrTokenMap(0L),
147     mp3DSphereObjectAttrTokenMap(0L),
148     mp3DSceneShapeAttrTokenMap(0L),
149     mp3DLightAttrTokenMap(0L),
150     mpPathShapeAttrTokenMap(0L),
151     mpPolygonShapeAttrTokenMap(0L),
152     msStartShape(RTL_CONSTASCII_USTRINGPARAM("StartShape")),
153     msEndShape(RTL_CONSTASCII_USTRINGPARAM("EndShape")),
154     msStartGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("StartGluePointIndex")),
155     msEndGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("EndGluePointIndex")),
156 
157     mrImporter( rImporter )
158 {
159     mpImpl = new XMLShapeImportHelperImpl();
160     mpImpl->mpSortContext = 0;
161 
162     // #88546# init to sal_False
163     mpImpl->mbHandleProgressBar = sal_False;
164 
165     mpSdPropHdlFactory = new XMLSdPropHdlFactory( rModel, rImporter );
166 
167     // set lock to avoid deletion
168     mpSdPropHdlFactory->acquire();
169 
170     // construct PropertySetMapper
171     UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper(mpSdPropHdlFactory);
172     mpPropertySetMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
173     // set lock to avoid deletion
174     mpPropertySetMapper->acquire();
175 
176     if( pExtMapper )
177     {
178         UniReference < SvXMLImportPropertyMapper > xExtMapper( pExtMapper );
179         mpPropertySetMapper->ChainImportMapper( xExtMapper );
180     }
181 
182     // chain text attributes
183     mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImporter));
184     mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaDefaultExtPropMapper(rImporter));
185 
186     // construct PresPagePropsMapper
187     xMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLSDPresPageProps, mpSdPropHdlFactory);
188     mpPresPagePropsMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
189     if(mpPresPagePropsMapper)
190     {
191         // set lock to avoid deletion
192         mpPresPagePropsMapper->acquire();
193     }
194 
195     uno::Reference< lang::XServiceInfo > xInfo( rImporter.GetModel(), uno::UNO_QUERY );
196     const OUString aSName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument") );
197     mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService( aSName );
198 }
199 
200 //////////////////////////////////////////////////////////////////////////////
201 
202 XMLShapeImportHelper::~XMLShapeImportHelper()
203 {
204     DBG_ASSERT( mpImpl->maConnections.empty(), "XMLShapeImportHelper::restoreConnections() was not called!" );
205 
206     // cleanup factory, decrease refcount. Should lead to destruction.
207     if(mpSdPropHdlFactory)
208     {
209         mpSdPropHdlFactory->release();
210         mpSdPropHdlFactory = 0L;
211     }
212 
213     // cleanup mapper, decrease refcount. Should lead to destruction.
214     if(mpPropertySetMapper)
215     {
216         mpPropertySetMapper->release();
217         mpPropertySetMapper = 0L;
218     }
219 
220     // cleanup presPage mapper, decrease refcount. Should lead to destruction.
221     if(mpPresPagePropsMapper)
222     {
223         mpPresPagePropsMapper->release();
224         mpPresPagePropsMapper = 0L;
225     }
226 
227     if(mpGroupShapeElemTokenMap) delete mpGroupShapeElemTokenMap;
228     if(mpFrameShapeElemTokenMap) delete mpFrameShapeElemTokenMap;
229 /*
230     if(mpShapeAttrTokenMap) delete mpShapeAttrTokenMap;
231     if(mpRectShapeAttrTokenMap) delete mpRectShapeAttrTokenMap;
232     if(mpLineShapeAttrTokenMap) delete mpLineShapeAttrTokenMap;
233     if(mpEllipseShapeAttrTokenMap) delete mpEllipseShapeAttrTokenMap;
234     if(mpTextBoxShapeAttrTokenMap) delete mpTextBoxShapeAttrTokenMap;
235     if(mpControlShapeAttrTokenMap) delete mpControlShapeAttrTokenMap;
236     if(mpPageShapeAttrTokenMap) delete mpPageShapeAttrTokenMap;
237     if(mpGraphicObjectShapeAttrTokenMap) delete mpGraphicObjectShapeAttrTokenMap;
238 */
239     if(mpPolygonShapeAttrTokenMap) delete mpPolygonShapeAttrTokenMap;
240     if(mpPathShapeAttrTokenMap) delete mpPathShapeAttrTokenMap;
241     if(mp3DSceneShapeElemTokenMap) delete mp3DSceneShapeElemTokenMap;
242     if(mp3DObjectAttrTokenMap) delete mp3DObjectAttrTokenMap;
243     if(mp3DPolygonBasedAttrTokenMap) delete mp3DPolygonBasedAttrTokenMap;
244     if(mp3DCubeObjectAttrTokenMap) delete mp3DCubeObjectAttrTokenMap;
245     if(mp3DSphereObjectAttrTokenMap) delete mp3DSphereObjectAttrTokenMap;
246     if(mp3DSceneShapeAttrTokenMap) delete mp3DSceneShapeAttrTokenMap;
247     if(mp3DLightAttrTokenMap) delete mp3DLightAttrTokenMap;
248 
249     // Styles or AutoStyles context?
250     if(mpStylesContext)
251     {
252         mpStylesContext->Clear();
253         mpStylesContext->ReleaseRef();
254     }
255 
256     if(mpAutoStylesContext)
257     {
258         mpAutoStylesContext->Clear();
259         mpAutoStylesContext->ReleaseRef();
260     }
261 
262     delete mpImpl;
263 }
264 
265 //////////////////////////////////////////////////////////////////////////////
266 
267 
268 
269 const SvXMLTokenMap& XMLShapeImportHelper::GetGroupShapeElemTokenMap()
270 {
271     if(!mpGroupShapeElemTokenMap)
272     {
273         static __FAR_DATA SvXMLTokenMapEntry aGroupShapeElemTokenMap[] =
274 {
275     { XML_NAMESPACE_DRAW,           XML_G,              XML_TOK_GROUP_GROUP         },
276     { XML_NAMESPACE_DRAW,           XML_RECT,           XML_TOK_GROUP_RECT          },
277     { XML_NAMESPACE_DRAW,           XML_LINE,           XML_TOK_GROUP_LINE          },
278     { XML_NAMESPACE_DRAW,           XML_CIRCLE,         XML_TOK_GROUP_CIRCLE        },
279     { XML_NAMESPACE_DRAW,           XML_ELLIPSE,        XML_TOK_GROUP_ELLIPSE       },
280     { XML_NAMESPACE_DRAW,           XML_POLYGON,        XML_TOK_GROUP_POLYGON       },
281     { XML_NAMESPACE_DRAW,           XML_POLYLINE,       XML_TOK_GROUP_POLYLINE      },
282     { XML_NAMESPACE_DRAW,           XML_PATH,           XML_TOK_GROUP_PATH          },
283 
284     { XML_NAMESPACE_DRAW,           XML_CONTROL,        XML_TOK_GROUP_CONTROL       },
285     { XML_NAMESPACE_DRAW,           XML_CONNECTOR,      XML_TOK_GROUP_CONNECTOR     },
286     { XML_NAMESPACE_DRAW,           XML_MEASURE,        XML_TOK_GROUP_MEASURE       },
287     { XML_NAMESPACE_DRAW,           XML_PAGE_THUMBNAIL, XML_TOK_GROUP_PAGE          },
288     { XML_NAMESPACE_DRAW,           XML_CAPTION,        XML_TOK_GROUP_CAPTION       },
289 
290     { XML_NAMESPACE_CHART,          XML_CHART,          XML_TOK_GROUP_CHART         },
291     { XML_NAMESPACE_DR3D,           XML_SCENE,          XML_TOK_GROUP_3DSCENE       },
292 
293     { XML_NAMESPACE_DRAW,           XML_FRAME,          XML_TOK_GROUP_FRAME         },
294     { XML_NAMESPACE_DRAW,           XML_CUSTOM_SHAPE,   XML_TOK_GROUP_CUSTOM_SHAPE  },
295 
296     { XML_NAMESPACE_DRAW,           XML_CUSTOM_SHAPE,   XML_TOK_GROUP_CUSTOM_SHAPE  },
297     { XML_NAMESPACE_OFFICE,         XML_ANNOTATION,     XML_TOK_GROUP_ANNOTATION    },
298     { XML_NAMESPACE_DRAW,           XML_A,              XML_TOK_GROUP_A             },
299 
300     XML_TOKEN_MAP_END
301 };
302 
303         mpGroupShapeElemTokenMap = new SvXMLTokenMap(aGroupShapeElemTokenMap);
304     } // if(!mpGroupShapeElemTokenMap)
305 
306     return *mpGroupShapeElemTokenMap;
307 }
308 
309 const SvXMLTokenMap& XMLShapeImportHelper::GetFrameShapeElemTokenMap()
310 {
311     if(!mpFrameShapeElemTokenMap)
312     {
313         static __FAR_DATA SvXMLTokenMapEntry aFrameShapeElemTokenMap[] =
314 {
315     { XML_NAMESPACE_DRAW,           XML_TEXT_BOX,       XML_TOK_FRAME_TEXT_BOX      },
316     { XML_NAMESPACE_DRAW,           XML_IMAGE,          XML_TOK_FRAME_IMAGE         },
317     { XML_NAMESPACE_DRAW,           XML_OBJECT,         XML_TOK_FRAME_OBJECT        },
318     { XML_NAMESPACE_DRAW,           XML_OBJECT_OLE,     XML_TOK_FRAME_OBJECT_OLE    },
319     { XML_NAMESPACE_DRAW,           XML_PLUGIN,         XML_TOK_FRAME_PLUGIN        },
320     { XML_NAMESPACE_DRAW,           XML_FLOATING_FRAME, XML_TOK_FRAME_FLOATING_FRAME},
321     { XML_NAMESPACE_DRAW,           XML_APPLET,         XML_TOK_FRAME_APPLET        },
322     { XML_NAMESPACE_TABLE,          XML_TABLE,          XML_TOK_FRAME_TABLE         },
323     XML_TOKEN_MAP_END
324 };
325 
326         mpFrameShapeElemTokenMap = new SvXMLTokenMap(aFrameShapeElemTokenMap);
327     } // if(!mpFrameShapeElemTokenMap)
328 
329     return *mpFrameShapeElemTokenMap;
330 }
331 
332 //////////////////////////////////////////////////////////////////////////////
333 
334 
335 const SvXMLTokenMap& XMLShapeImportHelper::Get3DSceneShapeElemTokenMap()
336 {
337     if(!mp3DSceneShapeElemTokenMap)
338     {
339         static __FAR_DATA SvXMLTokenMapEntry a3DSceneShapeElemTokenMap[] =
340 {
341     { XML_NAMESPACE_DR3D,           XML_SCENE,      XML_TOK_3DSCENE_3DSCENE     },
342     { XML_NAMESPACE_DR3D,           XML_CUBE,       XML_TOK_3DSCENE_3DCUBE      },
343     { XML_NAMESPACE_DR3D,           XML_SPHERE,     XML_TOK_3DSCENE_3DSPHERE    },
344     { XML_NAMESPACE_DR3D,           XML_ROTATE,     XML_TOK_3DSCENE_3DLATHE     },
345     { XML_NAMESPACE_DR3D,           XML_EXTRUDE,    XML_TOK_3DSCENE_3DEXTRUDE   },
346     XML_TOKEN_MAP_END
347 };
348 
349         mp3DSceneShapeElemTokenMap = new SvXMLTokenMap(a3DSceneShapeElemTokenMap);
350     } // if(!mp3DSceneShapeElemTokenMap)
351 
352     return *mp3DSceneShapeElemTokenMap;
353 }
354 
355 //////////////////////////////////////////////////////////////////////////////
356 /*
357 
358 const SvXMLTokenMap& XMLShapeImportHelper::GetShapeAttrTokenMap()
359 {
360     if(!mpShapeAttrTokenMap)
361     {
362     static __FAR_DATA SvXMLTokenMapEntry aShapeAttrTokenMap[] =
363 {
364     { XML_NAMESPACE_DRAW,           XML_NAME,               XML_TOK_SHAPE_NAME                          },
365     { XML_NAMESPACE_DRAW,           XML_STYLE_NAME,         XML_TOK_SHAPE_DRAWSTYLE_NAME_GRAPHICS       },
366     { XML_NAMESPACE_PRESENTATION,   XML_CLASS,              XML_TOK_SHAPE_PRESENTATION_CLASS            },
367     { XML_NAMESPACE_PRESENTATION,   XML_STYLE_NAME,         XML_TOK_SHAPE_DRAWSTYLE_NAME_PRESENTATION   },
368     { XML_NAMESPACE_SVG,            XML_TRANSFORM,          XML_TOK_SHAPE_TRANSFORM                     },
369     { XML_NAMESPACE_PRESENTATION,   XML_PLACEHOLDER,        XML_TOK_SHAPE_IS_PLACEHOLDER                },
370     { XML_NAMESPACE_PRESENTATION,   XML_USER_TRANSFORMED,   XML_TOK_SHAPE_IS_USER_TRANSFORMED           },
371     XML_TOKEN_MAP_END
372 };
373 
374         mpShapeAttrTokenMap = new SvXMLTokenMap(aShapeAttrTokenMap);
375         }
376 
377     return *mpShapeAttrTokenMap;
378 }
379 */
380 //////////////////////////////////////////////////////////////////////////////
381 
382 
383 const SvXMLTokenMap& XMLShapeImportHelper::Get3DObjectAttrTokenMap()
384 {
385     if(!mp3DObjectAttrTokenMap)
386     {
387         static __FAR_DATA SvXMLTokenMapEntry a3DObjectAttrTokenMap[] =
388 {
389     { XML_NAMESPACE_DRAW,           XML_STYLE_NAME,         XML_TOK_3DOBJECT_DRAWSTYLE_NAME     },
390     { XML_NAMESPACE_DR3D,           XML_TRANSFORM,          XML_TOK_3DOBJECT_TRANSFORM          },
391     XML_TOKEN_MAP_END
392 };
393 
394         mp3DObjectAttrTokenMap = new SvXMLTokenMap(a3DObjectAttrTokenMap);
395     } // if(!mp3DObjectAttrTokenMap)
396 
397     return *mp3DObjectAttrTokenMap;
398 }
399 
400 //////////////////////////////////////////////////////////////////////////////
401 
402 
403 const SvXMLTokenMap& XMLShapeImportHelper::Get3DPolygonBasedAttrTokenMap()
404 {
405     if(!mp3DPolygonBasedAttrTokenMap)
406     {
407         static __FAR_DATA SvXMLTokenMapEntry a3DPolygonBasedAttrTokenMap[] =
408 {
409     { XML_NAMESPACE_SVG,            XML_VIEWBOX,            XML_TOK_3DPOLYGONBASED_VIEWBOX      },
410     { XML_NAMESPACE_SVG,            XML_D,                  XML_TOK_3DPOLYGONBASED_D            },
411     XML_TOKEN_MAP_END
412 };
413 
414         mp3DPolygonBasedAttrTokenMap = new SvXMLTokenMap(a3DPolygonBasedAttrTokenMap);
415     } // if(!mp3DPolygonBasedAttrTokenMap)
416 
417     return *mp3DPolygonBasedAttrTokenMap;
418 }
419 
420 //////////////////////////////////////////////////////////////////////////////
421 
422 
423 const SvXMLTokenMap& XMLShapeImportHelper::Get3DCubeObjectAttrTokenMap()
424 {
425     if(!mp3DCubeObjectAttrTokenMap)
426     {
427         static __FAR_DATA SvXMLTokenMapEntry a3DCubeObjectAttrTokenMap[] =
428 {
429     { XML_NAMESPACE_DR3D,           XML_MIN_EDGE,           XML_TOK_3DCUBEOBJ_MINEDGE   },
430     { XML_NAMESPACE_DR3D,           XML_MAX_EDGE,           XML_TOK_3DCUBEOBJ_MAXEDGE   },
431     XML_TOKEN_MAP_END
432 };
433 
434         mp3DCubeObjectAttrTokenMap = new SvXMLTokenMap(a3DCubeObjectAttrTokenMap);
435     } // if(!mp3DCubeObjectAttrTokenMap)
436 
437     return *mp3DCubeObjectAttrTokenMap;
438 }
439 
440 //////////////////////////////////////////////////////////////////////////////
441 
442 
443 const SvXMLTokenMap& XMLShapeImportHelper::Get3DSphereObjectAttrTokenMap()
444 {
445     if(!mp3DSphereObjectAttrTokenMap)
446     {
447         static __FAR_DATA SvXMLTokenMapEntry a3DSphereObjectAttrTokenMap[] =
448 {
449     { XML_NAMESPACE_DR3D,           XML_CENTER,             XML_TOK_3DSPHEREOBJ_CENTER  },
450     { XML_NAMESPACE_DR3D,           XML_SIZE,               XML_TOK_3DSPHEREOBJ_SIZE    },
451     XML_TOKEN_MAP_END
452 };
453 
454         mp3DSphereObjectAttrTokenMap = new SvXMLTokenMap(a3DSphereObjectAttrTokenMap);
455     } // if(!mp3DSphereObjectAttrTokenMap)
456 
457     return *mp3DSphereObjectAttrTokenMap;
458 }
459 
460 //////////////////////////////////////////////////////////////////////////////
461 /*
462 
463 const SvXMLTokenMap& XMLShapeImportHelper::GetRectShapeAttrTokenMap()
464 {
465     if(!mpRectShapeAttrTokenMap)
466     {
467     static __FAR_DATA SvXMLTokenMapEntry aRectShapeAttrTokenMap[] =
468 {
469     { XML_NAMESPACE_SVG,    XML_X,                  XML_TOK_RECTSHAPE_X                 },
470     { XML_NAMESPACE_SVG,    XML_Y,                  XML_TOK_RECTSHAPE_Y                 },
471     { XML_NAMESPACE_SVG,    XML_WIDTH,              XML_TOK_RECTSHAPE_WIDTH             },
472     { XML_NAMESPACE_SVG,    XML_HEIGHT,             XML_TOK_RECTSHAPE_HEIGHT            },
473     { XML_NAMESPACE_DRAW,   XML_CORNER_RADIUS,      XML_TOK_RECTSHAPE_CORNER_RADIUS     },
474     XML_TOKEN_MAP_END
475 };
476 
477         mpRectShapeAttrTokenMap = new SvXMLTokenMap(aRectShapeAttrTokenMap);
478         }
479 
480     return *mpRectShapeAttrTokenMap;
481 }
482 
483 //////////////////////////////////////////////////////////////////////////////
484 
485 
486 const SvXMLTokenMap& XMLShapeImportHelper::GetLineShapeAttrTokenMap()
487 {
488     if(!mpLineShapeAttrTokenMap)
489     {
490     static __FAR_DATA SvXMLTokenMapEntry aLineShapeAttrTokenMap[] =
491 {
492     { XML_NAMESPACE_SVG,    XML_X1,             XML_TOK_LINESHAPE_X1                },
493     { XML_NAMESPACE_SVG,    XML_Y1,             XML_TOK_LINESHAPE_Y1                },
494     { XML_NAMESPACE_SVG,    XML_X2,             XML_TOK_LINESHAPE_X2                },
495     { XML_NAMESPACE_SVG,    XML_Y2,             XML_TOK_LINESHAPE_Y2                },
496     XML_TOKEN_MAP_END
497 };
498 
499         mpLineShapeAttrTokenMap = new SvXMLTokenMap(aLineShapeAttrTokenMap);
500         }
501 
502     return *mpLineShapeAttrTokenMap;
503 }
504 
505 //////////////////////////////////////////////////////////////////////////////
506 
507 
508 const SvXMLTokenMap& XMLShapeImportHelper::GetEllipseShapeAttrTokenMap()
509 {
510     if(!mpEllipseShapeAttrTokenMap)
511     {
512     static __FAR_DATA SvXMLTokenMapEntry aEllipseShapeAttrTokenMap[] =
513 {
514     { XML_NAMESPACE_SVG,    XML_RX,             XML_TOK_ELLIPSESHAPE_RX             },
515     { XML_NAMESPACE_SVG,    XML_RY,             XML_TOK_ELLIPSESHAPE_RY             },
516     { XML_NAMESPACE_SVG,    XML_CX,             XML_TOK_ELLIPSESHAPE_CX             },
517     { XML_NAMESPACE_SVG,    XML_CY,             XML_TOK_ELLIPSESHAPE_CY             },
518     { XML_NAMESPACE_SVG,    XML_R,              XML_TOK_ELLIPSESHAPE_R              },
519     XML_TOKEN_MAP_END
520 };
521 
522         mpEllipseShapeAttrTokenMap = new SvXMLTokenMap(aEllipseShapeAttrTokenMap);
523         }
524 
525     return *mpEllipseShapeAttrTokenMap;
526 }
527 
528 //////////////////////////////////////////////////////////////////////////////
529 */
530 
531 const SvXMLTokenMap& XMLShapeImportHelper::GetPolygonShapeAttrTokenMap()
532 {
533     if(!mpPolygonShapeAttrTokenMap)
534     {
535         static __FAR_DATA SvXMLTokenMapEntry aPolygonShapeAttrTokenMap[] =
536 {
537     { XML_NAMESPACE_SVG,    XML_VIEWBOX,            XML_TOK_POLYGONSHAPE_VIEWBOX        },
538     { XML_NAMESPACE_DRAW,   XML_POINTS,             XML_TOK_POLYGONSHAPE_POINTS         },
539     XML_TOKEN_MAP_END
540 };
541 
542         mpPolygonShapeAttrTokenMap = new SvXMLTokenMap(aPolygonShapeAttrTokenMap);
543     } // if(!mpPolygonShapeAttrTokenMap)
544 
545     return *mpPolygonShapeAttrTokenMap;
546 }
547 
548 //////////////////////////////////////////////////////////////////////////////
549 
550 
551 const SvXMLTokenMap& XMLShapeImportHelper::GetPathShapeAttrTokenMap()
552 {
553     if(!mpPathShapeAttrTokenMap)
554     {
555         static __FAR_DATA SvXMLTokenMapEntry aPathShapeAttrTokenMap[] =
556 {
557     { XML_NAMESPACE_SVG,    XML_VIEWBOX,            XML_TOK_PATHSHAPE_VIEWBOX           },
558     { XML_NAMESPACE_SVG,    XML_D,                  XML_TOK_PATHSHAPE_D                 },
559     XML_TOKEN_MAP_END
560 };
561 
562         mpPathShapeAttrTokenMap = new SvXMLTokenMap(aPathShapeAttrTokenMap);
563     } // if(!mpPathShapeAttrTokenMap)
564 
565     return *mpPathShapeAttrTokenMap;
566 }
567 /*
568 //////////////////////////////////////////////////////////////////////////////
569 
570 
571 const SvXMLTokenMap& XMLShapeImportHelper::GetTextBoxShapeAttrTokenMap()
572 {
573     if(!mpTextBoxShapeAttrTokenMap)
574     {
575     static __FAR_DATA SvXMLTokenMapEntry aTextBoxShapeAttrTokenMap[] =
576 {
577     { XML_NAMESPACE_SVG,    XML_X,                  XML_TOK_TEXTBOXSHAPE_X              },
578     { XML_NAMESPACE_SVG,    XML_Y,                  XML_TOK_TEXTBOXSHAPE_Y              },
579     { XML_NAMESPACE_SVG,    XML_WIDTH,              XML_TOK_TEXTBOXSHAPE_WIDTH          },
580     { XML_NAMESPACE_SVG,    XML_HEIGHT,             XML_TOK_TEXTBOXSHAPE_HEIGHT         },
581     XML_TOKEN_MAP_END
582 };
583 
584         mpTextBoxShapeAttrTokenMap = new SvXMLTokenMap(aTextBoxShapeAttrTokenMap);
585         }
586 
587     return *mpTextBoxShapeAttrTokenMap;
588 }
589 
590 //////////////////////////////////////////////////////////////////////////////
591 
592 
593 const SvXMLTokenMap& XMLShapeImportHelper::GetControlShapeAttrTokenMap()
594 {
595     if(!mpControlShapeAttrTokenMap)
596     {
597     static __FAR_DATA SvXMLTokenMapEntry aControlShapeAttrTokenMap[] =
598 {
599     { XML_NAMESPACE_SVG,    XML_X,                  XML_TOK_CONTROLSHAPE_X              },
600     { XML_NAMESPACE_SVG,    XML_Y,                  XML_TOK_CONTROLSHAPE_Y              },
601     { XML_NAMESPACE_SVG,    XML_WIDTH,              XML_TOK_CONTROLSHAPE_WIDTH          },
602     { XML_NAMESPACE_SVG,    XML_HEIGHT,             XML_TOK_CONTROLSHAPE_HEIGHT         },
603     XML_TOKEN_MAP_END
604 };
605 
606         mpControlShapeAttrTokenMap = new SvXMLTokenMap(aControlShapeAttrTokenMap);
607         }
608 
609     return *mpControlShapeAttrTokenMap;
610 }
611 */
612 //////////////////////////////////////////////////////////////////////////////
613 
614 
615 const SvXMLTokenMap& XMLShapeImportHelper::Get3DSceneShapeAttrTokenMap()
616 {
617     if(!mp3DSceneShapeAttrTokenMap)
618     {
619         static __FAR_DATA SvXMLTokenMapEntry a3DSceneShapeAttrTokenMap[] =
620 {
621     { XML_NAMESPACE_DR3D,   XML_TRANSFORM,          XML_TOK_3DSCENESHAPE_TRANSFORM      },
622     { XML_NAMESPACE_DR3D,   XML_VRP,                XML_TOK_3DSCENESHAPE_VRP            },
623     { XML_NAMESPACE_DR3D,   XML_VPN,                XML_TOK_3DSCENESHAPE_VPN            },
624     { XML_NAMESPACE_DR3D,   XML_VUP,                XML_TOK_3DSCENESHAPE_VUP            },
625     { XML_NAMESPACE_DR3D,   XML_PROJECTION,         XML_TOK_3DSCENESHAPE_PROJECTION     },
626     { XML_NAMESPACE_DR3D,   XML_DISTANCE,           XML_TOK_3DSCENESHAPE_DISTANCE       },
627     { XML_NAMESPACE_DR3D,   XML_FOCAL_LENGTH,       XML_TOK_3DSCENESHAPE_FOCAL_LENGTH   },
628     { XML_NAMESPACE_DR3D,   XML_SHADOW_SLANT,       XML_TOK_3DSCENESHAPE_SHADOW_SLANT   },
629     { XML_NAMESPACE_DR3D,   XML_SHADE_MODE,         XML_TOK_3DSCENESHAPE_SHADE_MODE     },
630     { XML_NAMESPACE_DR3D,   XML_AMBIENT_COLOR,      XML_TOK_3DSCENESHAPE_AMBIENT_COLOR  },
631     { XML_NAMESPACE_DR3D,   XML_LIGHTING_MODE,      XML_TOK_3DSCENESHAPE_LIGHTING_MODE  },
632     XML_TOKEN_MAP_END
633 };
634 
635         mp3DSceneShapeAttrTokenMap = new SvXMLTokenMap(a3DSceneShapeAttrTokenMap);
636     } // if(!mp3DSceneShapeAttrTokenMap)
637 
638     return *mp3DSceneShapeAttrTokenMap;
639 }
640 
641 //////////////////////////////////////////////////////////////////////////////
642 
643 
644 const SvXMLTokenMap& XMLShapeImportHelper::Get3DLightAttrTokenMap()
645 {
646     if(!mp3DLightAttrTokenMap)
647     {
648         static __FAR_DATA SvXMLTokenMapEntry a3DLightAttrTokenMap[] =
649 {
650     { XML_NAMESPACE_DR3D,   XML_DIFFUSE_COLOR,      XML_TOK_3DLIGHT_DIFFUSE_COLOR       },
651     { XML_NAMESPACE_DR3D,   XML_DIRECTION,          XML_TOK_3DLIGHT_DIRECTION           },
652     { XML_NAMESPACE_DR3D,   XML_ENABLED,            XML_TOK_3DLIGHT_ENABLED             },
653     { XML_NAMESPACE_DR3D,   XML_SPECULAR,           XML_TOK_3DLIGHT_SPECULAR            },
654     XML_TOKEN_MAP_END
655 };
656 
657         mp3DLightAttrTokenMap = new SvXMLTokenMap(a3DLightAttrTokenMap);
658     } // if(!mp3DLightAttrTokenMap)
659 
660     return *mp3DLightAttrTokenMap;
661 }
662 
663 //////////////////////////////////////////////////////////////////////////////
664 /*
665 
666 const SvXMLTokenMap& XMLShapeImportHelper::GetPageShapeAttrTokenMap()
667 {
668     if(!mpPageShapeAttrTokenMap)
669     {
670     static __FAR_DATA SvXMLTokenMapEntry aPageShapeAttrTokenMap[] =
671 {
672     { XML_NAMESPACE_SVG,    XML_X,                  XML_TOK_PAGESHAPE_X             },
673     { XML_NAMESPACE_SVG,    XML_Y,                  XML_TOK_PAGESHAPE_Y             },
674     { XML_NAMESPACE_SVG,    XML_WIDTH,              XML_TOK_PAGESHAPE_WIDTH         },
675     { XML_NAMESPACE_SVG,    XML_HEIGHT,             XML_TOK_PAGESHAPE_HEIGHT        },
676     XML_TOKEN_MAP_END
677 };
678 
679         mpPageShapeAttrTokenMap = new SvXMLTokenMap(aPageShapeAttrTokenMap);
680         }
681 
682     return *mpPageShapeAttrTokenMap;
683 }
684 
685 //////////////////////////////////////////////////////////////////////////////
686 
687 
688 const SvXMLTokenMap& XMLShapeImportHelper::GetGraphicObjectShapeAttrTokenMap()
689 {
690     if(!mpGraphicObjectShapeAttrTokenMap)
691     {
692     static __FAR_DATA SvXMLTokenMapEntry aGraphicObjectShapeAttrTokenMap[] =
693 {
694     { XML_NAMESPACE_SVG,    XML_X,                  XML_TOK_GOSHAPE_X                   },
695     { XML_NAMESPACE_SVG,    XML_Y,                  XML_TOK_GOSHAPE_Y                   },
696     { XML_NAMESPACE_SVG,    XML_WIDTH,              XML_TOK_GOSHAPE_WIDTH               },
697     { XML_NAMESPACE_SVG,    XML_HEIGHT,             XML_TOK_GOSHAPE_HEIGHT              },
698     { XML_NAMESPACE_XLINK,  XML_HREF,               XML_TOK_GOSHAPE_URL                 },
699     XML_TOKEN_MAP_END
700 };
701 
702         mpGraphicObjectShapeAttrTokenMap = new SvXMLTokenMap(aGraphicObjectShapeAttrTokenMap);
703         }
704 
705     return *mpGraphicObjectShapeAttrTokenMap;
706 }
707 */
708 //////////////////////////////////////////////////////////////////////////////
709 
710 SvXMLShapeContext* XMLShapeImportHelper::Create3DSceneChildContext(
711     SvXMLImport& rImport,
712     sal_uInt16 p_nPrefix,
713     const OUString& rLocalName,
714     const uno::Reference< xml::sax::XAttributeList>& xAttrList,
715     uno::Reference< drawing::XShapes >& rShapes)
716 {
717     SdXMLShapeContext *pContext = 0L;
718 
719     if(rShapes.is())
720     {
721         const SvXMLTokenMap& rTokenMap = Get3DSceneShapeElemTokenMap();
722         switch(rTokenMap.Get(p_nPrefix, rLocalName))
723         {
724             case XML_TOK_3DSCENE_3DSCENE:
725             {
726                 // dr3d:3dscene inside dr3d:3dscene context
727                 pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
728                 break;
729             }
730             case XML_TOK_3DSCENE_3DCUBE:
731             {
732                 // dr3d:3dcube inside dr3d:3dscene context
733                 pContext = new SdXML3DCubeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
734                 break;
735             }
736             case XML_TOK_3DSCENE_3DSPHERE:
737             {
738                 // dr3d:3dsphere inside dr3d:3dscene context
739                 pContext = new SdXML3DSphereObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
740                 break;
741             }
742             case XML_TOK_3DSCENE_3DLATHE:
743             {
744                 // dr3d:3dlathe inside dr3d:3dscene context
745                 pContext = new SdXML3DLatheObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
746                 break;
747             }
748             case XML_TOK_3DSCENE_3DEXTRUDE:
749             {
750                 // dr3d:3dextrude inside dr3d:3dscene context
751                 pContext = new SdXML3DExtrudeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
752                 break;
753             }
754         }
755     }
756 
757     // now parse the attribute list and call the child context for each unknown attribute
758     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
759     for(sal_Int16 a(0); a < nAttrCount; a++)
760     {
761         const OUString& rAttrName = xAttrList->getNameByIndex(a);
762         OUString aLocalName;
763         sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
764         const OUString aValue( xAttrList->getValueByIndex(a) );
765 
766         pContext->processAttribute( nPrefix, aLocalName, aValue );
767     }
768 
769     return pContext;
770 }
771 
772 //////////////////////////////////////////////////////////////////////////////
773 
774 void XMLShapeImportHelper::SetStylesContext(SvXMLStylesContext* pNew)
775 {
776     mpStylesContext = pNew;
777     mpStylesContext->AddRef();
778 }
779 
780 //////////////////////////////////////////////////////////////////////////////
781 
782 void XMLShapeImportHelper::SetAutoStylesContext(SvXMLStylesContext* pNew)
783 {
784     mpAutoStylesContext = pNew;
785     mpAutoStylesContext->AddRef();
786 }
787 
788 //////////////////////////////////////////////////////////////////////////////
789 
790 SvXMLShapeContext* XMLShapeImportHelper::CreateGroupChildContext(
791     SvXMLImport& rImport,
792     sal_uInt16 p_nPrefix,
793     const OUString& rLocalName,
794     const uno::Reference< xml::sax::XAttributeList>& xAttrList,
795     uno::Reference< drawing::XShapes >& rShapes,
796     sal_Bool bTemporaryShape)
797 {
798     SdXMLShapeContext *pContext = 0L;
799 
800     const SvXMLTokenMap& rTokenMap = GetGroupShapeElemTokenMap();
801     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
802 
803     switch(rTokenMap.Get(p_nPrefix, rLocalName))
804     {
805         case XML_TOK_GROUP_GROUP:
806         {
807             // draw:g inside group context (RECURSIVE)
808             pContext = new SdXMLGroupShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
809             break;
810         }
811         case XML_TOK_GROUP_3DSCENE:
812         {
813             // dr3d:3dscene inside group context
814             pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
815             break;
816         }
817         case XML_TOK_GROUP_RECT:
818         {
819             // draw:rect inside group context
820             pContext = new SdXMLRectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
821             break;
822         }
823         case XML_TOK_GROUP_LINE:
824         {
825             // draw:line inside group context
826             pContext = new SdXMLLineShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
827             break;
828         }
829         case XML_TOK_GROUP_CIRCLE:
830         case XML_TOK_GROUP_ELLIPSE:
831         {
832             // draw:circle or draw:ellipse inside group context
833             pContext = new SdXMLEllipseShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
834             break;
835         }
836         case XML_TOK_GROUP_POLYGON:
837         case XML_TOK_GROUP_POLYLINE:
838         {
839             // draw:polygon or draw:polyline inside group context
840             pContext = new SdXMLPolygonShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes,
841                 rTokenMap.Get(p_nPrefix, rLocalName) == XML_TOK_GROUP_POLYGON ? sal_True : sal_False, bTemporaryShape );
842             break;
843         }
844         case XML_TOK_GROUP_PATH:
845         {
846             // draw:path inside group context
847             pContext = new SdXMLPathShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
848             break;
849         }
850         case XML_TOK_GROUP_FRAME:
851         {
852             // text:text-box inside group context
853             pContext = new SdXMLFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
854             break;
855         }
856         case XML_TOK_GROUP_CONTROL:
857         {
858             // draw:control inside group context
859             pContext = new SdXMLControlShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
860             break;
861         }
862         case XML_TOK_GROUP_CONNECTOR:
863         {
864             // draw:connector inside group context
865             pContext = new SdXMLConnectorShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
866             break;
867         }
868         case XML_TOK_GROUP_MEASURE:
869         {
870             // draw:measure inside group context
871             pContext = new SdXMLMeasureShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
872             break;
873         }
874         case XML_TOK_GROUP_PAGE:
875         {
876             // draw:page inside group context
877             pContext = new SdXMLPageShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
878             break;
879         }
880         case XML_TOK_GROUP_CAPTION:
881         case XML_TOK_GROUP_ANNOTATION:
882         {
883             // draw:caption inside group context
884             pContext = new SdXMLCaptionShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
885             break;
886         }
887         case XML_TOK_GROUP_CHART:
888         {
889             // chart:chart inside group context
890             pContext = new SdXMLChartShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
891             break;
892         }
893         case XML_TOK_GROUP_CUSTOM_SHAPE:
894         {
895             // draw:customshape
896             pContext = new SdXMLCustomShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
897             break;
898         }
899         case XML_TOK_GROUP_A:
900         {
901             return new SdXMLShapeLinkContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes );
902         }
903         // add other shapes here...
904         default:
905             return new SvXMLShapeContext( rImport, p_nPrefix, rLocalName, bTemporaryShape );
906     }
907 
908     // now parse the attribute list and call the child context for each unknown attribute
909     for(sal_Int16 a(0); a < nAttrCount; a++)
910     {
911         const OUString& rAttrName = xAttrList->getNameByIndex(a);
912         OUString aLocalName;
913         sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
914         const OUString aValue( xAttrList->getValueByIndex(a) );
915 
916         pContext->processAttribute( nPrefix, aLocalName, aValue );
917     }
918 
919     return pContext;
920 }
921 
922 // This method is called from SdXMLFrameContext to create children of drawe:frame
923 SvXMLShapeContext* XMLShapeImportHelper::CreateFrameChildContext(
924     SvXMLImport& rImport,
925     sal_uInt16 p_nPrefix,
926     const OUString& rLocalName,
927     const uno::Reference< xml::sax::XAttributeList>& rAttrList,
928     uno::Reference< drawing::XShapes >& rShapes,
929     const uno::Reference< xml::sax::XAttributeList>& rFrameAttrList)
930 {
931     SdXMLShapeContext *pContext = 0L;
932 
933     const SvXMLTokenMap& rTokenMap = GetFrameShapeElemTokenMap();
934 
935     SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList );
936     if( rFrameAttrList.is() )
937         pAttrList->AppendAttributeList( rFrameAttrList );
938     uno::Reference < xml::sax::XAttributeList > xAttrList = pAttrList;
939 
940 
941     switch(rTokenMap.Get(p_nPrefix, rLocalName))
942     {
943         case XML_TOK_FRAME_TEXT_BOX:
944         {
945             // text:text-box inside group context
946             pContext = new SdXMLTextBoxShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
947             break;
948         }
949         case XML_TOK_FRAME_IMAGE:
950         {
951             // office:image inside group context
952             pContext = new SdXMLGraphicObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
953             break;
954         }
955         case XML_TOK_FRAME_OBJECT:
956         case XML_TOK_FRAME_OBJECT_OLE:
957         {
958             // draw:object or draw:object_ole
959             pContext = new SdXMLObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
960             break;
961         }
962         case XML_TOK_FRAME_TABLE:
963         {
964             // draw:object or draw:object_ole
965             if( rImport.IsTableShapeSupported() )
966                 pContext = new SdXMLTableShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes );
967             break;
968 
969         }
970         case XML_TOK_FRAME_PLUGIN:
971         {
972             // draw:plugin
973             pContext = new SdXMLPluginShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
974             break;
975         }
976         case XML_TOK_FRAME_FLOATING_FRAME:
977         {
978             // draw:floating-frame
979             pContext = new SdXMLFloatingFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
980             break;
981         }
982         case XML_TOK_FRAME_APPLET:
983         {
984             // draw:applet
985             pContext = new SdXMLAppletShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
986             break;
987         }
988         // add other shapes here...
989         default:
990             break;
991     }
992 
993     if( pContext )
994     {
995         // now parse the attribute list and call the child context for each unknown attribute
996         sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
997         for(sal_Int16 a(0); a < nAttrCount; a++)
998         {
999             const OUString& rAttrName = xAttrList->getNameByIndex(a);
1000             OUString aLocalName;
1001             sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
1002             const OUString aValue( xAttrList->getValueByIndex(a) );
1003 
1004             pContext->processAttribute( nPrefix, aLocalName, aValue );
1005         }
1006     }
1007 
1008     return pContext;
1009 }
1010 
1011 SvXMLImportContext *XMLShapeImportHelper::CreateFrameChildContext(
1012     SvXMLImportContext *pThisContext,
1013     sal_uInt16 nPrefix,
1014     const OUString& rLocalName,
1015     const uno::Reference< xml::sax::XAttributeList>& xAttrList )
1016 {
1017     SvXMLImportContext * pContext = NULL;
1018 
1019     SdXMLFrameShapeContext *pFrameContext = PTR_CAST( SdXMLFrameShapeContext, pThisContext );
1020     if( pFrameContext )
1021         pContext = pFrameContext->CreateChildContext( nPrefix, rLocalName, xAttrList );
1022 
1023     return pContext;
1024 }
1025 
1026 
1027 /** this function is called whenever the implementation classes like to add this new
1028     shape to the given XShapes.
1029 */
1030 void XMLShapeImportHelper::addShape( uno::Reference< drawing::XShape >& rShape,
1031                                      const uno::Reference< xml::sax::XAttributeList >&,
1032                                      uno::Reference< drawing::XShapes >& rShapes)
1033 {
1034     if( rShape.is() && rShapes.is() )
1035     {
1036         // add new shape to parent
1037         rShapes->add( rShape );
1038     }
1039 }
1040 
1041 /** this function is called whenever the implementation classes have finished importing
1042     a shape to the given XShapes. The shape is already inserted into its XShapes and
1043     all properties and styles are set.
1044 */
1045 void XMLShapeImportHelper::finishShape(
1046         com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape,
1047         const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >&,
1048         com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >&)
1049 {
1050     // --> OD 2004-08-10 #i28749#, #i36248# - set property <PositionLayoutDir>
1051     // to <PositionInHoriL2R>, if it exists and the import states that
1052     // the shape positioning attributes are in horizontal left-to-right
1053     // layout. This is the case for the OpenOffice.org file format.
1054     // This setting is done for Writer documents, because the property
1055     // only exists at service com::sun::star::text::Shape - the Writer
1056     // UNO service for shapes.
1057     // The value indicates that the positioning attributes are given
1058     // in horizontal left-to-right layout. The property is evaluated
1059     // during the first positioning of the shape in order to convert
1060     // the shape position given in the OpenOffice.org file format to
1061     // the one for the OASIS Open Office file format.
1062     uno::Reference< beans::XPropertySet > xPropSet(rShape, uno::UNO_QUERY);
1063     if ( xPropSet.is() )
1064     {
1065         if ( mrImporter.IsShapePositionInHoriL2R() &&
1066              xPropSet->getPropertySetInfo()->hasPropertyByName(
1067                 OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir"))) )
1068         {
1069             uno::Any aPosLayoutDir;
1070             aPosLayoutDir <<= text::PositionLayoutDir::PositionInHoriL2R;
1071             xPropSet->setPropertyValue(
1072                 OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir")),
1073                 aPosLayoutDir );
1074         }
1075     }
1076     // <--
1077 }
1078 
1079 // helper functions for z-order sorting
1080 struct ZOrderHint
1081 {
1082     sal_Int32 nIs;
1083     sal_Int32 nShould;
1084 
1085     int operator<(const ZOrderHint& rComp) const { return nShould < rComp.nShould; }
1086 };
1087 
1088 class ShapeSortContext
1089 {
1090 public:
1091     uno::Reference< drawing::XShapes > mxShapes;
1092     list<ZOrderHint>              maZOrderList;
1093     list<ZOrderHint>              maUnsortedList;
1094 
1095     sal_Int32                     mnCurrentZ;
1096     ShapeSortContext*             mpParentContext;
1097     const OUString                msZOrder;
1098 
1099     ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext = NULL );
1100 
1101     void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos );
1102 };
1103 
1104 ShapeSortContext::ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext )
1105 :   mxShapes( rShapes ), mnCurrentZ( 0 ), mpParentContext( pParentContext ),
1106     msZOrder(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))
1107 {
1108 }
1109 
1110 void ShapeSortContext::moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos )
1111 {
1112     uno::Any aAny( mxShapes->getByIndex( nSourcePos ) );
1113     uno::Reference< beans::XPropertySet > xPropSet;
1114     aAny >>= xPropSet;
1115 
1116     if( xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName( msZOrder ) )
1117     {
1118         aAny <<= nDestPos;
1119         xPropSet->setPropertyValue( msZOrder, aAny );
1120 
1121         list<ZOrderHint>::iterator aIter = maZOrderList.begin();
1122         list<ZOrderHint>::iterator aEnd = maZOrderList.end();
1123 
1124         while( aIter != aEnd )
1125         {
1126             if( (*aIter).nIs < nSourcePos )
1127             {
1128                 DBG_ASSERT( (*aIter).nIs >= nDestPos, "Shape sorting failed" );
1129                 (*aIter).nIs++;
1130             }
1131             aIter++;
1132         }
1133 
1134         aIter = maUnsortedList.begin();
1135         aEnd = maUnsortedList.end();
1136 
1137         while( aIter != aEnd )
1138         {
1139             if( (*aIter).nIs < nSourcePos )
1140             {
1141                 DBG_ASSERT( (*aIter).nIs >= nDestPos, "shape sorting failed" );
1142                 (*aIter).nIs++;
1143             }
1144             aIter++;
1145         }
1146     }
1147 }
1148 
1149 void XMLShapeImportHelper::pushGroupForSorting( uno::Reference< drawing::XShapes >& rShapes )
1150 {
1151     mpImpl->mpSortContext = new ShapeSortContext( rShapes, mpImpl->mpSortContext );
1152 }
1153 
1154 void XMLShapeImportHelper::popGroupAndSort()
1155 {
1156     DBG_ASSERT( mpImpl->mpSortContext, "No context to sort!" );
1157     if( mpImpl->mpSortContext == NULL )
1158         return;
1159 
1160     try
1161     {
1162         list<ZOrderHint>& rZList = mpImpl->mpSortContext->maZOrderList;
1163         list<ZOrderHint>& rUnsortedList = mpImpl->mpSortContext->maUnsortedList;
1164 
1165         // sort shapes
1166         if( !rZList.empty() )
1167         {
1168             // only do something if we have shapes to sort
1169 
1170             // check if there are more shapes than inserted with ::shapeWithZIndexAdded()
1171             // This can happen if there where already shapes on the page before import
1172             // Since the writer may delete some of this shapes during import, we need
1173             // to do this here and not in our c'tor anymore
1174 
1175             // check if we have more shapes than we know of
1176             sal_Int32 nCount = mpImpl->mpSortContext->mxShapes->getCount();
1177 
1178             nCount -= rZList.size();
1179             nCount -= rUnsortedList.size();
1180 
1181 
1182             if( nCount > 0 )
1183             {
1184                 // first update offsets of added shapes
1185                 list<ZOrderHint>::iterator aIter( rZList.begin() );
1186                 while( aIter != rZList.end() )
1187                     (*aIter++).nIs += nCount;
1188 
1189                 aIter = rUnsortedList.begin();
1190                 while( aIter != rUnsortedList.end() )
1191                     (*aIter++).nIs += nCount;
1192 
1193                 // second add the already existing shapes in the unsorted list
1194                 ZOrderHint aNewHint;
1195 
1196                 do
1197                 {
1198                     nCount--;
1199 
1200                     aNewHint.nIs = nCount;
1201                     aNewHint.nShould = -1;
1202 
1203                     rUnsortedList.insert(rUnsortedList.begin(), aNewHint);
1204                 }
1205                 while( nCount );
1206             }
1207 
1208             // sort z ordered shapes
1209             rZList.sort();
1210 
1211             // this is the current index, all shapes before that
1212             // index are finished
1213             sal_Int32 nIndex = 0;
1214             while( !rZList.empty() )
1215             {
1216                 list<ZOrderHint>::iterator aIter( rZList.begin() );
1217 
1218                 while( nIndex < (*aIter).nShould && !rUnsortedList.empty() )
1219                 {
1220                     ZOrderHint aGapHint( *rUnsortedList.begin() );
1221                     rUnsortedList.pop_front();
1222 
1223                     mpImpl->mpSortContext->moveShape( aGapHint.nIs, nIndex++ );
1224                 }
1225 
1226                 if( (*aIter).nIs != nIndex )
1227                     mpImpl->mpSortContext->moveShape( (*aIter).nIs, nIndex );
1228 
1229                 rZList.pop_front();
1230                 nIndex++;
1231             }
1232         }
1233     }
1234     catch( uno::Exception& )
1235     {
1236         DBG_ERROR("exception while sorting shapes, sorting failed!");
1237     }
1238 
1239     // put parent on top and delete current context, were done
1240     ShapeSortContext* pContext = mpImpl->mpSortContext;
1241     mpImpl->mpSortContext = pContext->mpParentContext;
1242     delete pContext;
1243 }
1244 
1245 void XMLShapeImportHelper::shapeWithZIndexAdded( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >&, sal_Int32 nZIndex )
1246 {
1247     if( mpImpl->mpSortContext)
1248     {
1249         ZOrderHint aNewHint;
1250         aNewHint.nIs = mpImpl->mpSortContext->mnCurrentZ++;
1251         aNewHint.nShould = nZIndex;
1252 
1253         if( nZIndex == -1 )
1254         {
1255             // don't care, so add to unsorted list
1256             mpImpl->mpSortContext->maUnsortedList.push_back(aNewHint);
1257         }
1258         else
1259         {
1260             // insert into sort list
1261             mpImpl->mpSortContext->maZOrderList.push_back(aNewHint);
1262         }
1263     }
1264 }
1265 
1266 void XMLShapeImportHelper::addShapeConnection( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rConnectorShape,
1267                          sal_Bool bStart,
1268                          const rtl::OUString& rDestShapeId,
1269                          sal_Int32 nDestGlueId )
1270 {
1271     ConnectionHint aHint;
1272     aHint.mxConnector = rConnectorShape;
1273     aHint.bStart = bStart;
1274     aHint.aDestShapeId = rDestShapeId;
1275     aHint.nDestGlueId = nDestGlueId;
1276 
1277     mpImpl->maConnections.push_back( aHint );
1278 }
1279 
1280 void XMLShapeImportHelper::restoreConnections()
1281 {
1282     if( !mpImpl->maConnections.empty() )
1283     {
1284         uno::Any aAny;
1285 
1286         const vector<ConnectionHint>::size_type nCount = mpImpl->maConnections.size();
1287         for( vector<ConnectionHint>::size_type i = 0; i < nCount; i++ )
1288         {
1289             ConnectionHint& rHint = mpImpl->maConnections[i];
1290             uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY );
1291             if( xConnector.is() )
1292             {
1293                 // #86637# remember line deltas
1294                 uno::Any aLine1Delta;
1295                 uno::Any aLine2Delta;
1296                 uno::Any aLine3Delta;
1297                 OUString aStr1(RTL_CONSTASCII_USTRINGPARAM("EdgeLine1Delta"));
1298                 OUString aStr2(RTL_CONSTASCII_USTRINGPARAM("EdgeLine2Delta"));
1299                 OUString aStr3(RTL_CONSTASCII_USTRINGPARAM("EdgeLine3Delta"));
1300                 aLine1Delta = xConnector->getPropertyValue(aStr1);
1301                 aLine2Delta = xConnector->getPropertyValue(aStr2);
1302                 aLine3Delta = xConnector->getPropertyValue(aStr3);
1303 
1304                 // #86637# simply setting these values WILL force the connector to do
1305                 // an new layout promptly. So the line delta values have to be rescued
1306                 // and restored around connector changes.
1307                 uno::Reference< drawing::XShape > xShape(
1308                     mrImporter.getInterfaceToIdentifierMapper().getReference( rHint.aDestShapeId ), uno::UNO_QUERY );
1309                 if( xShape.is() )
1310                 {
1311                     aAny <<= xShape;
1312                     xConnector->setPropertyValue( rHint.bStart ? msStartShape : msEndShape, aAny );
1313 
1314                     sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId : getGluePointId( xShape, rHint.nDestGlueId );
1315                     aAny <<= nGlueId;
1316                     xConnector->setPropertyValue( rHint.bStart ? msStartGluePointIndex : msEndGluePointIndex, aAny );
1317                 }
1318 
1319                 // #86637# restore line deltas
1320                 xConnector->setPropertyValue(aStr1, aLine1Delta );
1321                 xConnector->setPropertyValue(aStr2, aLine2Delta );
1322                 xConnector->setPropertyValue(aStr3, aLine3Delta );
1323             }
1324         }
1325         mpImpl->maConnections.clear();
1326     }
1327 }
1328 
1329 SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport )
1330 {
1331     UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport );
1332     UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory );
1333     SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport );
1334 
1335     // chain text attributes
1336     pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) );
1337     return pResult;
1338 }
1339 
1340 /** creates a shape property set mapper that can be used for non shape elements.
1341     Only current feature is that the ShapeUserDefinedAttributes property is not included in this one. */
1342 SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateExternalShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport )
1343 {
1344     UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport );
1345     UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory, 1 );
1346     SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport );
1347 
1348     // chain text attributes
1349     pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) );
1350     return pResult;
1351 }
1352 
1353 /** adds a mapping for a glue point identifier from an xml file to the identifier created after inserting
1354     the new glue point into the core. The saved mappings can be retrieved by getGluePointId() */
1355 void XMLShapeImportHelper::addGluePointMapping( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape,
1356                           sal_Int32 nSourceId, sal_Int32 nDestinnationId )
1357 {
1358     if( mpPageContext )
1359         mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
1360 }
1361 
1362 /** moves all current DestinationId's by n */
1363 void XMLShapeImportHelper::moveGluePointMapping( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, const sal_Int32 n )
1364 {
1365     if( mpPageContext )
1366     {
1367         ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
1368         if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
1369         {
1370             GluePointIdMap::iterator aShapeIdIter = (*aShapeIter).second.begin();
1371             GluePointIdMap::iterator aShapeIdEnd  = (*aShapeIter).second.end();
1372             while ( aShapeIdIter != aShapeIdEnd )
1373             {
1374                 if ( (*aShapeIdIter).second != -1 )
1375                     (*aShapeIdIter).second += n;
1376                 aShapeIdIter++;
1377             }
1378         }
1379     }
1380 }
1381 
1382 /** retrieves a mapping for a glue point identifier from the current xml file to the identifier created after
1383     inserting the new glue point into the core. The mapping must be initialized first with addGluePointMapping() */
1384 sal_Int32 XMLShapeImportHelper::getGluePointId( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId )
1385 {
1386     if( mpPageContext )
1387     {
1388         ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
1389         if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
1390         {
1391             GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId);
1392             if( aIdIter != (*aShapeIter).second.end() )
1393                 return (*aIdIter).second;
1394         }
1395     }
1396 
1397     return -1;
1398 }
1399 
1400 /** this method must be calling before the first shape is imported for the given page */
1401 void XMLShapeImportHelper::startPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes )
1402 {
1403     XMLShapeImportPageContextImpl* pOldContext = mpPageContext;
1404     mpPageContext = new XMLShapeImportPageContextImpl();
1405     mpPageContext->mpNext = pOldContext;
1406     mpPageContext->mxShapes = rShapes;
1407 }
1408 
1409 /** this method must be calling after the last shape is imported for the given page */
1410 void XMLShapeImportHelper::endPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >&
1411 #ifdef DBG_UTIL
1412 rShapes
1413 #endif
1414 )
1415 {
1416     DBG_ASSERT( mpPageContext && (mpPageContext->mxShapes == rShapes), "wrong call to endPage(), no startPage called or wrong page" );
1417     if( NULL == mpPageContext )
1418         return;
1419 
1420     restoreConnections();
1421 
1422     XMLShapeImportPageContextImpl* pNextContext = mpPageContext->mpNext;
1423     delete mpPageContext;
1424     mpPageContext = pNextContext;
1425 }
1426 
1427 // #88546#
1428 /** defines if the import should increment the progress bar or not */
1429 void XMLShapeImportHelper::enableHandleProgressBar( sal_Bool bEnable )
1430 {
1431     mpImpl->mbHandleProgressBar = bEnable;
1432 }
1433 
1434 sal_Bool XMLShapeImportHelper::IsHandleProgressBarEnabled() const
1435 {
1436     return mpImpl->mbHandleProgressBar;
1437 }
1438 
1439 /** queries the capability of the current model to create presentation shapes */
1440 sal_Bool XMLShapeImportHelper::IsPresentationShapesSupported()
1441 {
1442     return mpImpl->mbIsPresentationShapesSupported;
1443 }
1444 
1445 const rtl::Reference< XMLTableImport >& XMLShapeImportHelper::GetShapeTableImport()
1446 {
1447     if( !mxShapeTableImport.is() )
1448     {
1449         rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrImporter.GetModel(), mrImporter ) );
1450         rtl::Reference< XMLPropertySetMapper > xPropertySetMapper( new XMLShapePropertySetMapper( xFactory.get() ) );
1451         mxShapeTableImport = new XMLTableImport( mrImporter, xPropertySetMapper, xFactory );
1452     }
1453 
1454     return mxShapeTableImport;
1455 }
1456 
1457 void SvXMLShapeContext::setHyperlink( const OUString& rHyperlink )
1458 {
1459     msHyperlink = rHyperlink;
1460 }
1461