xref: /aoo41x/main/xmloff/source/draw/shapeimport.cxx (revision cdf0e10c)
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