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 #include <tools/debug.hxx>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/text/TextContentAnchorType.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/text/XTextFrame.hpp>
35 #include <com/sun/star/container/XNamed.hpp>
36 #include <com/sun/star/text/SizeType.hpp>
37 #include <com/sun/star/drawing/XShape.hpp>
38 #include <com/sun/star/document/XEventsSupplier.hpp>
39 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
40 #include <com/sun/star/io/XOutputStream.hpp>
41 #include <com/sun/star/text/HoriOrientation.hpp>
42 #include <com/sun/star/text/VertOrientation.hpp>
43 #include <xmloff/xmlimp.hxx>
44 #include <xmloff/xmltoken.hxx>
45 #include "xmloff/xmlnmspe.hxx"
46 #include <xmloff/nmspmap.hxx>
47 #include <xmloff/xmluconv.hxx>
48 #include "XMLAnchorTypePropHdl.hxx"
49 #include "XMLEmbeddedObjectImportContext.hxx"
50 #include <xmloff/XMLBase64ImportContext.hxx>
51 #include "XMLReplacementImageContext.hxx"
52 #include <xmloff/prstylei.hxx>
53 #include "xmloff/i18nmap.hxx"
54 #include "xexptran.hxx"
55 #include <xmloff/shapeimport.hxx>
56 #include <xmloff/XMLEventsImportContext.hxx>
57 #include "XMLImageMapContext.hxx"
58 #include "XMLTextFrameContext.hxx"
59 
60 #include "XMLTextListBlockContext.hxx"
61 #include "XMLTextListItemContext.hxx"
62 #include <xmloff/attrlist.hxx>
63 #include <comphelper/stl_types.hxx>
64 
65 #include <map>
66 
67 
68 using ::rtl::OUString;
69 using ::rtl::OUStringBuffer;
70 
71 using namespace ::com::sun::star;
72 using namespace ::com::sun::star::uno;
73 using namespace ::com::sun::star::text;
74 using namespace ::com::sun::star::xml::sax;
75 using namespace ::com::sun::star::beans;
76 using namespace ::com::sun::star::lang;
77 using namespace ::com::sun::star::container;
78 using namespace ::com::sun::star::drawing;
79 using namespace ::com::sun::star::document;
80 using namespace ::xmloff::token;
81 using ::com::sun::star::document::XEventsSupplier;
82 
83 #define XML_TEXT_FRAME_TEXTBOX 1
84 #define XML_TEXT_FRAME_GRAPHIC 2
85 #define XML_TEXT_FRAME_OBJECT 3
86 #define XML_TEXT_FRAME_OBJECT_OLE 4
87 #define XML_TEXT_FRAME_APPLET 5
88 #define XML_TEXT_FRAME_PLUGIN 6
89 #define XML_TEXT_FRAME_FLOATING_FRAME 7
90 
91 typedef ::std::map < const ::rtl::OUString, ::rtl::OUString, ::comphelper::UStringLess> ParamMap;
92 
93 class XMLTextFrameContextHyperlink_Impl
94 {
95 	OUString sHRef;
96 	OUString sName;
97 	OUString sTargetFrameName;
98 	sal_Bool bMap;
99 
100 public:
101 
102 	inline XMLTextFrameContextHyperlink_Impl( const OUString& rHRef,
103 					   const OUString& rName,
104 					   const OUString& rTargetFrameName,
105 					   sal_Bool bMap );
106 
107 	const OUString& GetHRef() const { return sHRef; }
108 	const OUString& GetName() const { return sName; }
109 	const OUString& GetTargetFrameName() const { return sTargetFrameName; }
110 	sal_Bool GetMap() const { return bMap; }
111 };
112 
113 inline XMLTextFrameContextHyperlink_Impl::XMLTextFrameContextHyperlink_Impl(
114 	const OUString& rHRef, const OUString& rName,
115 	const OUString& rTargetFrameName, sal_Bool bM ) :
116 	sHRef( rHRef ),
117 	sName( rName ),
118 	sTargetFrameName( rTargetFrameName ),
119 	bMap( bM )
120 {
121 }
122 
123 // --> OD 2009-07-22 #i73249#
124 class XMLTextFrameTitleOrDescContext_Impl : public SvXMLImportContext
125 {
126     OUString&   mrTitleOrDesc;
127 
128 public:
129 
130 	TYPEINFO();
131 
132     XMLTextFrameTitleOrDescContext_Impl( SvXMLImport& rImport,
133                                          sal_uInt16 nPrfx,
134                                          const ::rtl::OUString& rLName,
135                                          OUString& rTitleOrDesc );
136     virtual ~XMLTextFrameTitleOrDescContext_Impl();
137 
138 	virtual void Characters( const OUString& rText );
139 };
140 
141 TYPEINIT1( XMLTextFrameTitleOrDescContext_Impl, SvXMLImportContext );
142 
143 XMLTextFrameTitleOrDescContext_Impl::XMLTextFrameTitleOrDescContext_Impl(
144 		SvXMLImport& rImport,
145         sal_uInt16 nPrfx,
146         const OUString& rLName,
147         OUString& rTitleOrDesc )
148     : SvXMLImportContext( rImport, nPrfx, rLName )
149     , mrTitleOrDesc( rTitleOrDesc )
150 {
151 }
152 
153 XMLTextFrameTitleOrDescContext_Impl::~XMLTextFrameTitleOrDescContext_Impl()
154 {
155 }
156 
157 void XMLTextFrameTitleOrDescContext_Impl::Characters( const OUString& rText )
158 {
159     mrTitleOrDesc += rText;
160 }
161 // <--
162 
163 // ------------------------------------------------------------------------
164 
165 class XMLTextFrameParam_Impl : public SvXMLImportContext
166 {
167 public:
168 
169 	TYPEINFO();
170 
171 	XMLTextFrameParam_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
172 								  const ::rtl::OUString& rLName,
173 			const ::com::sun::star::uno::Reference<
174 				::com::sun::star::xml::sax::XAttributeList > & xAttrList,
175 			sal_uInt16 nType,
176             ParamMap &rParamMap);
177 	virtual ~XMLTextFrameParam_Impl();
178 };
179 
180 TYPEINIT1( XMLTextFrameParam_Impl, SvXMLImportContext );
181 
182 XMLTextFrameParam_Impl::~XMLTextFrameParam_Impl()
183 {
184 }
185 
186 XMLTextFrameParam_Impl::XMLTextFrameParam_Impl(
187 		SvXMLImport& rImport, sal_uInt16 nPrfx,
188 	  	const ::rtl::OUString& rLName,
189 		const ::com::sun::star::uno::Reference<
190 				::com::sun::star::xml::sax::XAttributeList > & xAttrList,
191 		sal_uInt16 /*nType*/,
192         ParamMap &rParamMap):
193 	SvXMLImportContext( rImport, nPrfx, rLName )
194 {
195 	OUString sName, sValue;
196     sal_Bool bFoundValue = sal_False; // to allow empty values
197 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
198 	for( sal_Int16 i=0; i < nAttrCount; i++ )
199 	{
200 		const OUString& rAttrName = xAttrList->getNameByIndex( i );
201 		const OUString& rValue = xAttrList->getValueByIndex( i );
202 
203 		OUString aLocalName;
204 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
205 		if ( XML_NAMESPACE_DRAW == nPrefix )
206 		{
207 		   	if( IsXMLToken(aLocalName, XML_VALUE) )
208 			{
209 				sValue = rValue;
210 				bFoundValue=sal_True;
211 			}
212 			else if( IsXMLToken(aLocalName, XML_NAME) )
213 			{
214 				sName = rValue;
215 			}
216 		}
217 	}
218 	if (sName.getLength() && bFoundValue )
219         rParamMap[sName] = sValue;
220 }
221 class XMLTextFrameContourContext_Impl : public SvXMLImportContext
222 {
223 	Reference < XPropertySet > xPropSet;
224 
225 public:
226 
227 	TYPEINFO();
228 
229 	XMLTextFrameContourContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
230 								  const ::rtl::OUString& rLName,
231 			const ::com::sun::star::uno::Reference<
232 				::com::sun::star::xml::sax::XAttributeList > & xAttrList,
233 			const Reference < XPropertySet >& rPropSet,
234 			sal_Bool bPath );
235 	virtual ~XMLTextFrameContourContext_Impl();
236 };
237 
238 TYPEINIT1( XMLTextFrameContourContext_Impl, SvXMLImportContext );
239 
240 XMLTextFrameContourContext_Impl::XMLTextFrameContourContext_Impl(
241 		SvXMLImport& rImport,
242 		sal_uInt16 nPrfx, const OUString& rLName,
243 		const Reference< XAttributeList > & xAttrList,
244 		const Reference < XPropertySet >& rPropSet,
245 	    sal_Bool bPath ) :
246 	SvXMLImportContext( rImport, nPrfx, rLName ),
247 	xPropSet( rPropSet )
248 {
249 	OUString sD, sPoints, sViewBox;
250 	sal_Bool bPixelWidth = sal_False, bPixelHeight = sal_False;
251 	sal_Bool bAuto = sal_False;
252 	sal_Int32 nWidth = 0;
253 	sal_Int32 nHeight = 0;
254 
255 	const SvXMLTokenMap& rTokenMap =
256 		GetImport().GetTextImport()->GetTextContourAttrTokenMap();
257 
258 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
259 	for( sal_Int16 i=0; i < nAttrCount; i++ )
260 	{
261 		const OUString& rAttrName = xAttrList->getNameByIndex( i );
262 		const OUString& rValue = xAttrList->getValueByIndex( i );
263 
264 		OUString aLocalName;
265 		sal_uInt16 nPrefix =
266 			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
267 															&aLocalName );
268 		switch( rTokenMap.Get( nPrefix, aLocalName ) )
269 		{
270 		case XML_TOK_TEXT_CONTOUR_VIEWBOX:
271 			sViewBox = rValue;
272 			break;
273 		case XML_TOK_TEXT_CONTOUR_D:
274 			if( bPath )
275 				sD = rValue;
276 			break;
277 		case XML_TOK_TEXT_CONTOUR_POINTS:
278 			if( !bPath )
279 				sPoints = rValue;
280 			break;
281 		case XML_TOK_TEXT_CONTOUR_WIDTH:
282 			if( GetImport().GetMM100UnitConverter().convertMeasurePx( nWidth,
283 																	  rValue) )
284 				bPixelWidth = sal_True;
285 			else
286 				GetImport().GetMM100UnitConverter().convertMeasure( nWidth,
287 																rValue);
288 			break;
289 		case XML_TOK_TEXT_CONTOUR_HEIGHT:
290 			if( GetImport().GetMM100UnitConverter().convertMeasurePx( nHeight,
291 																rValue) )
292 				bPixelHeight = sal_True;
293 			else
294 				GetImport().GetMM100UnitConverter().convertMeasure( nHeight,
295 																	rValue);
296 			break;
297 		case XML_TOK_TEXT_CONTOUR_AUTO:
298 			bAuto = IsXMLToken(rValue, XML_TRUE);
299 			break;
300 		}
301 	}
302 
303 	OUString sContourPolyPolygon(
304 			RTL_CONSTASCII_USTRINGPARAM("ContourPolyPolygon") );
305 	Reference < XPropertySetInfo > xPropSetInfo =
306 		rPropSet->getPropertySetInfo();
307 	if( xPropSetInfo->hasPropertyByName(
308 													sContourPolyPolygon ) &&
309 		nWidth > 0 && nHeight > 0 && bPixelWidth == bPixelHeight &&
310 		(bPath ? sD : sPoints).getLength() )
311 	{
312 		awt::Point aPoint( 0,  0 );
313 		awt::Size aSize( nWidth, nHeight );
314 		SdXMLImExViewBox aViewBox( sViewBox,
315 								   GetImport().GetMM100UnitConverter());
316 		Any aAny;
317 		if( bPath )
318 		{
319 			SdXMLImExSvgDElement aPoints( sD, aViewBox, aPoint, aSize,
320 										  GetImport().GetMM100UnitConverter() );
321 			aAny <<= aPoints.GetPointSequenceSequence();
322 		}
323 		else
324 		{
325 			SdXMLImExPointsElement aPoints( sPoints, aViewBox, aPoint, aSize,
326 										GetImport().GetMM100UnitConverter() );
327 			aAny <<= aPoints.GetPointSequenceSequence();
328 		}
329 
330 		OUString sIsPixelContour(
331 				RTL_CONSTASCII_USTRINGPARAM("IsPixelContour") );
332 		xPropSet->setPropertyValue( sContourPolyPolygon, aAny );
333 
334 		if( xPropSetInfo->hasPropertyByName( sIsPixelContour ) )
335 		{
336 			aAny.setValue( &bPixelWidth, ::getBooleanCppuType() );
337 			xPropSet->setPropertyValue( sIsPixelContour, aAny );
338 		}
339 
340 		OUString sIsAutomaticContour(
341 				RTL_CONSTASCII_USTRINGPARAM("IsAutomaticContour") );
342 		if( xPropSetInfo->hasPropertyByName( sIsAutomaticContour ) )
343 		{
344 			aAny.setValue( &bAuto, ::getBooleanCppuType() );
345 			xPropSet->setPropertyValue( sIsAutomaticContour, aAny );
346 		}
347 	}
348 }
349 
350 XMLTextFrameContourContext_Impl::~XMLTextFrameContourContext_Impl()
351 {
352 }
353 
354 // ------------------------------------------------------------------------
355 
356 class XMLTextFrameContext_Impl : public SvXMLImportContext
357 {
358 	::com::sun::star::uno::Reference <
359 		::com::sun::star::text::XTextCursor > xOldTextCursor;
360 	::com::sun::star::uno::Reference <
361 		::com::sun::star::beans::XPropertySet > xPropSet;
362 	::com::sun::star::uno::Reference <
363 		::com::sun::star::io::XOutputStream > xBase64Stream;
364 
365     /// old list item and block (#89891#)
366     bool mbListContextPushed;
367 
368 	const ::rtl::OUString sWidth;
369 	const ::rtl::OUString sWidthType;
370 	const ::rtl::OUString sRelativeWidth;
371 	const ::rtl::OUString sHeight;
372 	const ::rtl::OUString sRelativeHeight;
373 	const ::rtl::OUString sSizeType;
374 	const ::rtl::OUString sIsSyncWidthToHeight;
375 	const ::rtl::OUString sIsSyncHeightToWidth;
376 	const ::rtl::OUString sHoriOrient;
377 	const ::rtl::OUString sHoriOrientPosition;
378 	const ::rtl::OUString sVertOrient;
379 	const ::rtl::OUString sVertOrientPosition;
380 	const ::rtl::OUString sChainNextName;
381 	const ::rtl::OUString sAnchorType;
382 	const ::rtl::OUString sAnchorPageNo;
383 	const ::rtl::OUString sGraphicURL;
384 	const ::rtl::OUString sGraphicFilter;
385     // --> OD 2009-07-22 #i73249#
386 //    const ::rtl::OUString sAlternativeText;
387     const ::rtl::OUString sTitle;
388     const ::rtl::OUString sDescription;
389     // <--
390 	const ::rtl::OUString sFrameStyleName;
391 	const ::rtl::OUString sGraphicRotation;
392 	const ::rtl::OUString sTextBoxServiceName;
393 	const ::rtl::OUString sGraphicServiceName;
394 
395 	::rtl::OUString	sName;
396 	::rtl::OUString	sStyleName;
397 	::rtl::OUString	sNextName;
398 	::rtl::OUString	sHRef;
399 	::rtl::OUString	sFilterName;
400 	::rtl::OUString	sCode;
401 	::rtl::OUString	sObject;
402 	::rtl::OUString	sArchive;
403 	::rtl::OUString	sMimeType;
404 	::rtl::OUString sFrameName;
405 	::rtl::OUString sAppletName;
406 	::rtl::OUString	sFilterService;
407 	::rtl::OUString sBase64CharsLeft;
408 	::rtl::OUString	sTblName;
409 
410     ParamMap aParamMap;
411 
412 	sal_Int32	nX;
413 	sal_Int32	nY;
414 	sal_Int32	nWidth;
415 	sal_Int32	nHeight;
416 	sal_Int32	nZIndex;
417 	sal_Int16	nPage;
418 	sal_Int16	nRotation;
419 	sal_Int16	nRelWidth;
420 	sal_Int16	nRelHeight;
421 
422 	sal_uInt16 nType;
423 	::com::sun::star::text::TextContentAnchorType 	eAnchorType;
424 
425 	sal_Bool	bMayScript : 1;
426 	sal_Bool	bMinWidth : 1;
427 	sal_Bool	bMinHeight : 1;
428 	sal_Bool	bSyncWidth : 1;
429 	sal_Bool	bSyncHeight : 1;
430 	sal_Bool	bCreateFailed : 1;
431 	sal_Bool	bOwnBase64Stream : 1;
432 
433 	void Create( sal_Bool bHRefOrBase64 );
434 
435 public:
436 
437 	TYPEINFO();
438 
439 	sal_Bool CreateIfNotThere();
440 
441 	XMLTextFrameContext_Impl( SvXMLImport& rImport,
442 			sal_uInt16 nPrfx,
443 			const ::rtl::OUString& rLName,
444 			const ::com::sun::star::uno::Reference<
445 				::com::sun::star::xml::sax::XAttributeList > & rAttrList,
446 			::com::sun::star::text::TextContentAnchorType eAnchorType,
447 			sal_uInt16 nType,
448 			const ::com::sun::star::uno::Reference<
449 				::com::sun::star::xml::sax::XAttributeList > & rFrameAttrList );
450 	virtual ~XMLTextFrameContext_Impl();
451 
452 	virtual void EndElement();
453 
454 	virtual void Characters( const ::rtl::OUString& rChars );
455 
456 	SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
457 				const ::rtl::OUString& rLocalName,
458 			 	const ::com::sun::star::uno::Reference<
459 					::com::sun::star::xml::sax::XAttributeList > & xAttrList );
460 
461 	void SetHyperlink( const ::rtl::OUString& rHRef,
462 					   const ::rtl::OUString& rName,
463 					   const ::rtl::OUString& rTargetFrameName,
464 					   sal_Bool bMap );
465     // --> OD 2009-07-22 #i73249#
466     void SetTitle( const ::rtl::OUString& rTitle );
467     // <--
468     void SetDesc( const ::rtl::OUString& rDesc );
469 
470 	::com::sun::star::text::TextContentAnchorType GetAnchorType() const { return eAnchorType; }
471 
472 	const ::com::sun::star::uno::Reference <
473 		::com::sun::star::beans::XPropertySet >& GetPropSet() { return xPropSet; }
474 };
475 
476 TYPEINIT1( XMLTextFrameContext_Impl, SvXMLImportContext );
477 
478 void XMLTextFrameContext_Impl::Create( sal_Bool /*bHRefOrBase64*/ )
479 {
480 	UniReference < XMLTextImportHelper > xTextImportHelper =
481 		GetImport().GetTextImport();
482 
483     switch ( nType)
484     {
485         case XML_TEXT_FRAME_OBJECT:
486         case XML_TEXT_FRAME_OBJECT_OLE:
487 			if( xBase64Stream.is() )
488 			{
489 				OUString sURL( GetImport().ResolveEmbeddedObjectURLFromBase64() );
490 				if( sURL.getLength() )
491 					xPropSet = GetImport().GetTextImport()
492 							->createAndInsertOLEObject( GetImport(), sURL,
493 														sStyleName,
494 														sTblName,
495 														nWidth, nHeight );
496 			}
497 			else if( sHRef.getLength() )
498 			{
499 				OUString sURL( GetImport().ResolveEmbeddedObjectURL( sHRef,
500 																OUString() ) );
501 
502 				if( GetImport().IsPackageURL( sHRef ) )
503 				{
504 					xPropSet = GetImport().GetTextImport()
505 							->createAndInsertOLEObject( GetImport(), sURL,
506 														sStyleName,
507 														sTblName,
508 														nWidth, nHeight );
509 				}
510 				else
511 				{
512 					// it should be an own OOo link that has no storage persistance
513 					xPropSet = GetImport().GetTextImport()
514 							->createAndInsertOOoLink( GetImport(),
515 														sURL,
516 														sStyleName,
517 														sTblName,
518 														nWidth, nHeight );
519 				}
520 			}
521 			else
522 			{
523 				OUString sURL( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.ServiceName:") );
524 				sURL += sFilterService;
525 				xPropSet = GetImport().GetTextImport()
526 							->createAndInsertOLEObject( GetImport(), sURL,
527 														sStyleName,
528 														sTblName,
529 														nWidth, nHeight );
530 
531 			}
532 			break;
533         case XML_TEXT_FRAME_APPLET:
534         {
535             xPropSet = GetImport().GetTextImport()
536 							->createAndInsertApplet( sAppletName, sCode,
537 													 bMayScript, sHRef,
538 													 nWidth, nHeight);
539             break;
540         }
541         case XML_TEXT_FRAME_PLUGIN:
542         {
543             if(sHRef.getLength())
544                 GetImport().GetAbsoluteReference(sHRef);
545             xPropSet = GetImport().GetTextImport()
546 							->createAndInsertPlugin( sMimeType, sHRef,
547 								   				 	 nWidth, nHeight);
548 
549             break;
550         }
551         case XML_TEXT_FRAME_FLOATING_FRAME:
552         {
553             xPropSet = GetImport().GetTextImport()
554 							->createAndInsertFloatingFrame( sFrameName, sHRef,
555 															sStyleName,
556 															nWidth, nHeight);
557             break;
558         }
559 	    default:
560         {
561             Reference<XMultiServiceFactory> xFactory( GetImport().GetModel(),
562                                                       UNO_QUERY );
563             if( xFactory.is() )
564             {
565                 OUString sServiceName;
566                 switch( nType )
567                 {
568                     case XML_TEXT_FRAME_TEXTBOX: sServiceName = sTextBoxServiceName; break;
569                     case XML_TEXT_FRAME_GRAPHIC: sServiceName = sGraphicServiceName; break;
570                 }
571                 Reference<XInterface> xIfc = xFactory->createInstance( sServiceName );
572                 DBG_ASSERT( xIfc.is(), "couldn't create frame" );
573                 if( xIfc.is() )
574                     xPropSet = Reference < XPropertySet >( xIfc, UNO_QUERY );
575             }
576         }
577     }
578 
579 	if( !xPropSet.is() )
580 	{
581 		bCreateFailed = sal_True;
582 		return;
583 	}
584 
585 	Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
586 
587 	// set name
588 	Reference < XNamed > xNamed( xPropSet, UNO_QUERY );
589 	if( xNamed.is() )
590 	{
591 		OUString sOrigName( xNamed->getName() );
592 		if( !sOrigName.getLength() ||
593 			(sName.getLength() && sOrigName != sName) )
594 		{
595 			OUString sOldName( sName );
596 			sal_Int32 i = 0;
597 			while( xTextImportHelper->HasFrameByName( sName ) )
598 			{
599 				sName = sOldName;
600 				sName += OUString::valueOf( ++i );
601 			}
602 			xNamed->setName( sName );
603 			if( sName != sOldName )
604 				xTextImportHelper->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_FRAME,
605 											 sOldName, sName );
606 		}
607 	}
608 
609 	// frame style
610 	XMLPropStyleContext *pStyle = 0;
611 	if( sStyleName.getLength() )
612 	{
613 		pStyle = xTextImportHelper->FindAutoFrameStyle( sStyleName );
614 		if( pStyle )
615             sStyleName = pStyle->GetParentName();
616 	}
617 
618 	Any aAny;
619 	if( sStyleName.getLength() )
620 	{
621 		OUString sDisplayStyleName( GetImport().GetStyleDisplayName(
622 							XML_STYLE_FAMILY_SD_GRAPHICS_ID, sStyleName ) );
623 		const Reference < XNameContainer > & rStyles =
624 			xTextImportHelper->GetFrameStyles();
625 		if( rStyles.is() &&
626 			rStyles->hasByName( sDisplayStyleName ) )
627 		{
628 			aAny <<= sDisplayStyleName;
629 			xPropSet->setPropertyValue( sFrameStyleName, aAny );
630 		}
631 	}
632 
633 	// anchor type (must be set before any other properties, because
634 	// otherwise some orientations cannot be set or will be changed
635 	// afterwards)
636 	aAny <<= eAnchorType;
637 	xPropSet->setPropertyValue( sAnchorType, aAny );
638 
639 	// hard properties
640 	if( pStyle )
641 		pStyle->FillPropertySet( xPropSet );
642 
643 
644 	// x and y
645 	sal_Int16 nHoriOrient =  HoriOrientation::NONE;
646 	aAny = xPropSet->getPropertyValue( sHoriOrient );
647 	aAny >>= nHoriOrient;
648 	if( HoriOrientation::NONE == nHoriOrient )
649 	{
650 		aAny <<= nX;
651 		xPropSet->setPropertyValue( sHoriOrientPosition, aAny );
652 	}
653 
654 	sal_Int16 nVertOrient =  VertOrientation::NONE;
655 	aAny = xPropSet->getPropertyValue( sVertOrient );
656 	aAny >>= nVertOrient;
657 	if( VertOrientation::NONE == nVertOrient )
658 	{
659 		aAny <<= nY;
660 		xPropSet->setPropertyValue( sVertOrientPosition, aAny );
661 	}
662 
663 	// width
664 	if( nWidth > 0 )
665 	{
666 		aAny <<= nWidth;
667 		xPropSet->setPropertyValue( sWidth, aAny );
668 	}
669 	if( nRelWidth > 0 || nWidth > 0 )
670 	{
671 		aAny <<= nRelWidth;
672 		xPropSet->setPropertyValue( sRelativeWidth, aAny );
673 	}
674 	if( bSyncWidth || nWidth > 0 )
675 	{
676 		sal_Bool bTmp = bSyncWidth;
677 		aAny.setValue( &bTmp, ::getBooleanCppuType() );
678 		xPropSet->setPropertyValue( sIsSyncWidthToHeight, aAny );
679 	}
680 	if( xPropSetInfo->hasPropertyByName( sWidthType ) &&
681 		(bMinWidth || nWidth > 0 || nRelWidth > 0 ) )
682 	{
683 		sal_Int16 nSizeType =
684 			(bMinWidth && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN
685                                                            : SizeType::FIX;
686 		aAny <<= nSizeType;
687 		xPropSet->setPropertyValue( sWidthType, aAny );
688 	}
689 
690 	if( nHeight > 0 )
691 	{
692 		aAny <<= nHeight;
693 		xPropSet->setPropertyValue( sHeight, aAny );
694 	}
695 	if( nRelHeight > 0 || nHeight > 0 )
696 	{
697 		aAny <<= nRelHeight;
698 		xPropSet->setPropertyValue( sRelativeHeight, aAny );
699 	}
700 	if( bSyncHeight || nHeight > 0 )
701 	{
702 		sal_Bool bTmp = bSyncHeight;
703 		aAny.setValue( &bTmp, ::getBooleanCppuType() );
704 		xPropSet->setPropertyValue( sIsSyncHeightToWidth, aAny );
705 	}
706 	if( xPropSetInfo->hasPropertyByName( sSizeType ) &&
707 		(bMinHeight || nHeight > 0 || nRelHeight > 0 ) )
708 	{
709 		sal_Int16 nSizeType =
710 			(bMinHeight && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN
711 															: SizeType::FIX;
712 		aAny <<= nSizeType;
713 		xPropSet->setPropertyValue( sSizeType, aAny );
714 	}
715 
716 	if( XML_TEXT_FRAME_GRAPHIC == nType )
717 	{
718 		// URL
719 		OSL_ENSURE( sHRef.getLength() > 0 || xBase64Stream.is(),
720 					"neither URL nor base64 image data given" );
721 		UniReference < XMLTextImportHelper > xTxtImport =
722 			GetImport().GetTextImport();
723 		if( sHRef.getLength() )
724 		{
725 			sal_Bool bForceLoad = xTxtImport->IsInsertMode() ||
726 								  xTxtImport->IsBlockMode() ||
727 								  xTxtImport->IsStylesOnlyMode() ||
728 								  xTxtImport->IsOrganizerMode();
729 			sHRef = GetImport().ResolveGraphicObjectURL( sHRef, !bForceLoad );
730 		}
731 		else if( xBase64Stream.is() )
732 		{
733 			sHRef = GetImport().ResolveGraphicObjectURLFromBase64( xBase64Stream );
734 			xBase64Stream = 0;
735 		}
736 		aAny <<= sHRef;
737 		xPropSet->setPropertyValue( sGraphicURL, aAny );
738 
739 		// filter name
740 		aAny <<=sFilterName;
741 		xPropSet->setPropertyValue( sGraphicFilter, aAny );
742 
743 		// rotation
744 		aAny <<= nRotation;
745 		xPropSet->setPropertyValue( sGraphicRotation, aAny );
746 	}
747 
748 	// page number (must be set after the frame is inserted, because it
749 	// will be overwritten then inserting the frame.
750 	if( TextContentAnchorType_AT_PAGE == eAnchorType && nPage > 0 )
751 	{
752 		aAny <<= nPage;
753 		xPropSet->setPropertyValue( sAnchorPageNo, aAny );
754 	}
755 
756 	if( XML_TEXT_FRAME_OBJECT != nType  &&
757 		XML_TEXT_FRAME_OBJECT_OLE != nType  &&
758 		XML_TEXT_FRAME_APPLET != nType &&
759 		XML_TEXT_FRAME_PLUGIN!= nType &&
760 		XML_TEXT_FRAME_FLOATING_FRAME != nType)
761 	{
762 		Reference < XTextContent > xTxtCntnt( xPropSet, UNO_QUERY );
763 		xTextImportHelper->InsertTextContent( xTxtCntnt );
764 	}
765 
766 	Reference < XShape > xShape( xPropSet, UNO_QUERY );
767 
768 	// #107848#
769 	// Make adding the shepe to Z-Ordering dependent from if we are
770 	// inside a inside_deleted_section (redlining). That is necessary
771 	// since the shape will be removed again later. It would lead to
772 	// errors if it would stay inside the Z-Ordering. Thus, the
773 	// easiest way to solve that conflict is to not add it here.
774 	if(!GetImport().HasTextImport()
775 		|| !GetImport().GetTextImport()->IsInsideDeleteContext())
776 	{
777 		GetImport().GetShapeImport()->shapeWithZIndexAdded( xShape, nZIndex );
778 	}
779 
780 	if( XML_TEXT_FRAME_TEXTBOX == nType )
781 	{
782 		xTextImportHelper->ConnectFrameChains( sName, sNextName, xPropSet );
783 		Reference < XTextFrame > xTxtFrame( xPropSet, UNO_QUERY );
784 		Reference < XText > xTxt = xTxtFrame->getText();
785 		xOldTextCursor = xTextImportHelper->GetCursor();
786 		xTextImportHelper->SetCursor( xTxt->createTextCursor() );
787 
788         // remember old list item and block (#89892#) and reset them
789         // for the text frame
790         xTextImportHelper->PushListContext();
791         mbListContextPushed = true;
792 	}
793 }
794 
795 sal_Bool XMLTextFrameContext_Impl::CreateIfNotThere()
796 {
797 	if( !xPropSet.is() &&
798 		( XML_TEXT_FRAME_OBJECT_OLE == nType ||
799 		  XML_TEXT_FRAME_GRAPHIC == nType ) &&
800 		xBase64Stream.is() && !bCreateFailed )
801 	{
802 		if( bOwnBase64Stream )
803 			xBase64Stream->closeOutput();
804 		Create( sal_True );
805 	}
806 
807 	return xPropSet.is();
808 }
809 
810 XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
811 		SvXMLImport& rImport,
812 		sal_uInt16 nPrfx, const OUString& rLName,
813 		const Reference< XAttributeList > & rAttrList,
814 		TextContentAnchorType eATyp,
815 		sal_uInt16 nNewType,
816 		const Reference< XAttributeList > & rFrameAttrList )
817 :	SvXMLImportContext( rImport, nPrfx, rLName )
818 ,   mbListContextPushed( false )
819 ,	sWidth(RTL_CONSTASCII_USTRINGPARAM("Width"))
820 ,	sWidthType(RTL_CONSTASCII_USTRINGPARAM("WidthType"))
821 ,	sRelativeWidth(RTL_CONSTASCII_USTRINGPARAM("RelativeWidth"))
822 ,	sHeight(RTL_CONSTASCII_USTRINGPARAM("Height"))
823 ,	sRelativeHeight(RTL_CONSTASCII_USTRINGPARAM("RelativeHeight"))
824 ,	sSizeType(RTL_CONSTASCII_USTRINGPARAM("SizeType"))
825 ,	sIsSyncWidthToHeight(RTL_CONSTASCII_USTRINGPARAM("IsSyncWidthToHeight"))
826 ,	sIsSyncHeightToWidth(RTL_CONSTASCII_USTRINGPARAM("IsSyncHeightToWidth"))
827 ,	sHoriOrient(RTL_CONSTASCII_USTRINGPARAM("HoriOrient"))
828 ,	sHoriOrientPosition(RTL_CONSTASCII_USTRINGPARAM("HoriOrientPosition"))
829 ,	sVertOrient(RTL_CONSTASCII_USTRINGPARAM("VertOrient"))
830 ,	sVertOrientPosition(RTL_CONSTASCII_USTRINGPARAM("VertOrientPosition"))
831 ,	sChainNextName(RTL_CONSTASCII_USTRINGPARAM("ChainNextName"))
832 ,	sAnchorType(RTL_CONSTASCII_USTRINGPARAM("AnchorType"))
833 ,	sAnchorPageNo(RTL_CONSTASCII_USTRINGPARAM("AnchorPageNo"))
834 ,	sGraphicURL(RTL_CONSTASCII_USTRINGPARAM("GraphicURL"))
835 ,	sGraphicFilter(RTL_CONSTASCII_USTRINGPARAM("GraphicFilter"))
836 // --> OD 2009-07-22 #i73249#
837 //,   sAlternativeText(RTL_CONSTASCII_USTRINGPARAM("AlternativeText"))
838 ,   sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
839 ,   sDescription(RTL_CONSTASCII_USTRINGPARAM("Description"))
840 // <--
841 ,	sFrameStyleName(RTL_CONSTASCII_USTRINGPARAM("FrameStyleName"))
842 ,	sGraphicRotation(RTL_CONSTASCII_USTRINGPARAM("GraphicRotation"))
843 ,	sTextBoxServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFrame"))
844 ,	sGraphicServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.GraphicObject"))
845 ,	nType( nNewType )
846 ,	eAnchorType( eATyp )
847 {
848 	nX = 0;
849 	nY = 0;
850 	nWidth = 0;
851 	nHeight = 0;
852 	nZIndex = -1;
853 	nPage = 0;
854 	nRotation = 0;
855 	nRelWidth = 0;
856 	nRelHeight = 0;
857 	bMayScript = sal_False;
858 
859 	bMinHeight = sal_False;
860 	bMinWidth = sal_False;
861 	bSyncWidth = sal_False;
862 	bSyncHeight = sal_False;
863 	bCreateFailed = sal_False;
864 	bOwnBase64Stream = sal_False;
865 
866 	UniReference < XMLTextImportHelper > xTxtImport =
867 		GetImport().GetTextImport();
868 	const SvXMLTokenMap& rTokenMap =
869 		xTxtImport->GetTextFrameAttrTokenMap();
870 
871 	sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
872 	sal_Int16 nTotalAttrCount = nAttrCount + (rFrameAttrList.is() ? rFrameAttrList->getLength() : 0);
873 	for( sal_Int16 i=0; i < nTotalAttrCount; i++ )
874 	{
875 		const OUString& rAttrName =
876 			i < nAttrCount ? rAttrList->getNameByIndex( i ) : rFrameAttrList->getNameByIndex( i-nAttrCount );
877 		const OUString& rValue =
878 			i < nAttrCount ? rAttrList->getValueByIndex( i ): rFrameAttrList->getValueByIndex( i-nAttrCount );
879 
880 		OUString aLocalName;
881 		sal_uInt16 nPrefix =
882 			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
883 															&aLocalName );
884 		switch( rTokenMap.Get( nPrefix, aLocalName ) )
885 		{
886 		case XML_TOK_TEXT_FRAME_STYLE_NAME:
887 			sStyleName = rValue;
888 			break;
889 		case XML_TOK_TEXT_FRAME_NAME:
890 			sName = rValue;
891 			break;
892 		case XML_TOK_TEXT_FRAME_FRAME_NAME:
893 			sFrameName = rValue;
894 			break;
895 		case XML_TOK_TEXT_FRAME_APPLET_NAME:
896 			sAppletName = rValue;
897 			break;
898 		case XML_TOK_TEXT_FRAME_ANCHOR_TYPE:
899 			if( TextContentAnchorType_AT_PARAGRAPH == eAnchorType ||
900 				TextContentAnchorType_AT_CHARACTER == eAnchorType ||
901 				TextContentAnchorType_AS_CHARACTER == eAnchorType )
902 			{
903 
904 				TextContentAnchorType eNew;
905 				if( XMLAnchorTypePropHdl::convert( rValue, eNew ) &&
906 					( TextContentAnchorType_AT_PARAGRAPH == eNew ||
907 					  TextContentAnchorType_AT_CHARACTER == eNew ||
908 					  TextContentAnchorType_AS_CHARACTER == eNew ||
909 					  TextContentAnchorType_AT_PAGE == eNew) )
910 					eAnchorType = eNew;
911 			}
912 			break;
913 		case XML_TOK_TEXT_FRAME_ANCHOR_PAGE_NUMBER:
914 			{
915 				sal_Int32 nTmp;
916 			   	if( GetImport().GetMM100UnitConverter().
917 								convertNumber( nTmp, rValue, 1, SHRT_MAX ) )
918 					nPage = (sal_Int16)nTmp;
919 			}
920 			break;
921 		case XML_TOK_TEXT_FRAME_X:
922 			GetImport().GetMM100UnitConverter().convertMeasure( nX, rValue );
923 			break;
924 		case XML_TOK_TEXT_FRAME_Y:
925 			GetImport().GetMM100UnitConverter().convertMeasure( nY, rValue );
926 			break;
927 		case XML_TOK_TEXT_FRAME_WIDTH:
928 			// relative widths are obsolete since SRC617. Remove them some day!
929 			if( rValue.indexOf( '%' ) != -1 )
930 			{
931 				sal_Int32 nTmp;
932 				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
933 																	rValue );
934 				nRelWidth = (sal_Int16)nTmp;
935 			}
936 			else
937 			{
938 				GetImport().GetMM100UnitConverter().convertMeasure( nWidth,
939 																	rValue, 0 );
940 			}
941 			break;
942 		case XML_TOK_TEXT_FRAME_REL_WIDTH:
943 			if( IsXMLToken(rValue, XML_SCALE) )
944 			{
945 				bSyncWidth = sal_True;
946 			}
947 			else
948 			{
949 				sal_Int32 nTmp;
950 				if( GetImport().GetMM100UnitConverter().
951 						convertPercent( nTmp, rValue ) )
952 					nRelWidth = (sal_Int16)nTmp;
953 			}
954 			break;
955 		case XML_TOK_TEXT_FRAME_MIN_WIDTH:
956 			if( rValue.indexOf( '%' ) != -1 )
957 			{
958 				sal_Int32 nTmp;
959 				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
960 																	rValue );
961 				nRelWidth = (sal_Int16)nTmp;
962 			}
963 			else
964 			{
965 				GetImport().GetMM100UnitConverter().convertMeasure( nWidth,
966 																	rValue, 0 );
967 			}
968 			bMinWidth = sal_True;
969 			break;
970 		case XML_TOK_TEXT_FRAME_HEIGHT:
971 			// relative heights are obsolete since SRC617. Remove them some day!
972 			if( rValue.indexOf( '%' ) != -1 )
973 			{
974 				sal_Int32 nTmp;
975 				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
976 																	rValue );
977 				nRelHeight = (sal_Int16)nTmp;
978 			}
979 			else
980 			{
981 				GetImport().GetMM100UnitConverter().convertMeasure( nHeight,
982 																	rValue, 0 );
983 			}
984 			break;
985 		case XML_TOK_TEXT_FRAME_REL_HEIGHT:
986 			if( IsXMLToken( rValue, XML_SCALE ) )
987 			{
988 				bSyncHeight = sal_True;
989 			}
990 			else if( IsXMLToken( rValue, XML_SCALE_MIN ) )
991 			{
992 				bSyncHeight = sal_True;
993 				bMinHeight = sal_True;
994 			}
995 			else
996 			{
997 				sal_Int32 nTmp;
998 				if( GetImport().GetMM100UnitConverter().
999 						convertPercent( nTmp, rValue ) )
1000 					nRelHeight = (sal_Int16)nTmp;
1001 			}
1002 			break;
1003 		case XML_TOK_TEXT_FRAME_MIN_HEIGHT:
1004 			if( rValue.indexOf( '%' ) != -1 )
1005 			{
1006 				sal_Int32 nTmp;
1007 				GetImport().GetMM100UnitConverter().convertPercent( nTmp,
1008 																	rValue );
1009 				nRelHeight = (sal_Int16)nTmp;
1010 			}
1011 			else
1012 			{
1013 				GetImport().GetMM100UnitConverter().convertMeasure( nHeight,
1014 																	rValue, 0 );
1015 			}
1016 			bMinHeight = sal_True;
1017 			break;
1018 		case XML_TOK_TEXT_FRAME_Z_INDEX:
1019 			GetImport().GetMM100UnitConverter().convertNumber( nZIndex, rValue, -1 );
1020 			break;
1021 		case XML_TOK_TEXT_FRAME_NEXT_CHAIN_NAME:
1022 			sNextName = rValue;
1023 			break;
1024 		case XML_TOK_TEXT_FRAME_HREF:
1025 			sHRef = rValue;
1026 			break;
1027 		case XML_TOK_TEXT_FRAME_FILTER_NAME:
1028 			sFilterName = rValue;
1029 			break;
1030 		case XML_TOK_TEXT_FRAME_TRANSFORM:
1031 			{
1032 				OUString sValue( rValue );
1033 				sValue.trim();
1034                 const OUString aRotate(GetXMLToken(XML_ROTATE));
1035 				const sal_Int32 nRotateLen(aRotate.getLength());
1036 				sal_Int32 nLen = sValue.getLength();
1037 				if( nLen >= nRotateLen+3 &&
1038 					0 == sValue.compareTo( aRotate, nRotateLen ) &&
1039 					'(' == sValue[nRotateLen] &&
1040 					')' == sValue[nLen-1] )
1041 				{
1042 					sValue = sValue.copy( nRotateLen+1, nLen-(nRotateLen+2) );
1043 					sValue.trim();
1044 					sal_Int32 nVal;
1045 					if( GetImport().GetMM100UnitConverter().convertNumber( nVal, sValue ) )
1046 						nRotation = (sal_Int16)(nVal % 360 );
1047 				}
1048 			}
1049 			break;
1050 		case XML_TOK_TEXT_FRAME_CODE:
1051 			sCode = rValue;
1052 			break;
1053 		case XML_TOK_TEXT_FRAME_OBJECT:
1054 			sObject = rValue;
1055 			break;
1056 		case XML_TOK_TEXT_FRAME_ARCHIVE:
1057 			sArchive = rValue;
1058 			break;
1059 		case XML_TOK_TEXT_FRAME_MAY_SCRIPT:
1060 			bMayScript = IsXMLToken( rValue, XML_TRUE );
1061 			break;
1062 		case XML_TOK_TEXT_FRAME_MIME_TYPE:
1063 			sMimeType = rValue;
1064 			break;
1065 		case XML_TOK_TEXT_FRAME_NOTIFY_ON_UPDATE:
1066 			sTblName = rValue;
1067 			break;
1068 		}
1069 	}
1070 
1071 	if( ( (XML_TEXT_FRAME_GRAPHIC == nType ||
1072 		   XML_TEXT_FRAME_OBJECT == nType ||
1073 		   XML_TEXT_FRAME_OBJECT_OLE == nType) &&
1074 		  !sHRef.getLength() ) ||
1075 		( XML_TEXT_FRAME_APPLET  == nType && !sCode.getLength() ) ||
1076         ( XML_TEXT_FRAME_PLUGIN == nType &&
1077           sHRef.getLength() == 0 && sMimeType.getLength() == 0 ) )
1078 		return;	// no URL: no image or OLE object
1079 
1080 	Create( sal_True );
1081 }
1082 
1083 XMLTextFrameContext_Impl::~XMLTextFrameContext_Impl()
1084 {
1085 }
1086 
1087 void XMLTextFrameContext_Impl::EndElement()
1088 {
1089 	CreateIfNotThere();
1090 
1091 	if( xOldTextCursor.is() )
1092 	{
1093 		GetImport().GetTextImport()->DeleteParagraph();
1094 		GetImport().GetTextImport()->SetCursor( xOldTextCursor );
1095 	}
1096 
1097     // reinstall old list item (if necessary) #89892#
1098     if (mbListContextPushed) {
1099         GetImport().GetTextImport()->PopListContext();
1100     }
1101 
1102 	if (( nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN ) && xPropSet.is())
1103 		GetImport().GetTextImport()->endAppletOrPlugin( xPropSet, aParamMap);
1104 }
1105 
1106 SvXMLImportContext *XMLTextFrameContext_Impl::CreateChildContext(
1107 		sal_uInt16 nPrefix,
1108 		const OUString& rLocalName,
1109 		const Reference< XAttributeList > & xAttrList )
1110 {
1111 	SvXMLImportContext *pContext = 0;
1112 
1113 	if( XML_NAMESPACE_DRAW == nPrefix )
1114 	{
1115 		if ( (nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN) &&
1116 			  IsXMLToken( rLocalName, XML_PARAM ) )
1117 		{
1118 			pContext = new XMLTextFrameParam_Impl( GetImport(),
1119 											  nPrefix, rLocalName,
1120 							 				  xAttrList, nType, aParamMap );
1121 		}
1122 	}
1123 	else if( (XML_NAMESPACE_OFFICE == nPrefix) )
1124 	{
1125 		if( IsXMLToken( rLocalName, XML_BINARY_DATA ) )
1126 		{
1127 			if( !xPropSet.is() && !xBase64Stream.is() && !bCreateFailed )
1128 			{
1129 				switch( nType )
1130 				{
1131 				case XML_TEXT_FRAME_GRAPHIC:
1132 					xBase64Stream =
1133 						GetImport().GetStreamForGraphicObjectURLFromBase64();
1134 					break;
1135 				case XML_TEXT_FRAME_OBJECT_OLE:
1136 					xBase64Stream =
1137 						GetImport().GetStreamForEmbeddedObjectURLFromBase64();
1138 					break;
1139 				}
1140 				if( xBase64Stream.is() )
1141 					pContext = new XMLBase64ImportContext( GetImport(), nPrefix,
1142 													rLocalName, xAttrList,
1143 													xBase64Stream );
1144 			}
1145 		}
1146 	}
1147     // --> OD 2009-08-17 #i100480#
1148     // correction of condition which also avoids warnings.
1149     if( !pContext &&
1150         ( XML_TEXT_FRAME_OBJECT == nType &&
1151           ( ( XML_NAMESPACE_OFFICE == nPrefix &&
1152               IsXMLToken( rLocalName, XML_DOCUMENT ) ) ||
1153             ( XML_NAMESPACE_MATH == nPrefix &&
1154               IsXMLToken( rLocalName, XML_MATH ) ) ) ) )
1155     // <--
1156 	{
1157 		if( !xPropSet.is() && !bCreateFailed )
1158 		{
1159 			XMLEmbeddedObjectImportContext *pEContext =
1160 				new XMLEmbeddedObjectImportContext( GetImport(), nPrefix,
1161 													rLocalName, xAttrList );
1162 			sFilterService = pEContext->GetFilterServiceName();
1163 			if( sFilterService.getLength() != 0 )
1164 			{
1165 				Create( sal_False );
1166 				if( xPropSet.is() )
1167 				{
1168 					Reference < XEmbeddedObjectSupplier > xEOS( xPropSet,
1169 																UNO_QUERY );
1170 					OSL_ENSURE( xEOS.is(),
1171 							"no embedded object supplier for own object" );
1172                     Reference<com::sun::star::lang::XComponent> aXComponent(xEOS->getEmbeddedObject());
1173 					pEContext->SetComponent( aXComponent );
1174 				}
1175 			}
1176 			pContext = pEContext;
1177 		}
1178 	}
1179 	if( !pContext && xOldTextCursor.is() )	// text-box
1180 		pContext = GetImport().GetTextImport()->CreateTextChildContext(
1181 							GetImport(), nPrefix, rLocalName, xAttrList,
1182 							XML_TEXT_TYPE_TEXTBOX );
1183 
1184 	if( !pContext )
1185 		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
1186 
1187 	return pContext;
1188 }
1189 
1190 void XMLTextFrameContext_Impl::Characters( const OUString& rChars )
1191 {
1192 	if( ( XML_TEXT_FRAME_OBJECT_OLE == nType ||
1193 		  XML_TEXT_FRAME_GRAPHIC == nType) &&
1194 		!xPropSet.is() && !bCreateFailed )
1195 	{
1196 		OUString sTrimmedChars( rChars. trim() );
1197 		if( sTrimmedChars.getLength() )
1198 		{
1199 			if( !xBase64Stream.is() )
1200 			{
1201 				if( XML_TEXT_FRAME_GRAPHIC == nType )
1202 				{
1203 					xBase64Stream =
1204 						GetImport().GetStreamForGraphicObjectURLFromBase64();
1205 				}
1206 				else
1207 				{
1208 					xBase64Stream =
1209 						GetImport().GetStreamForEmbeddedObjectURLFromBase64();
1210 				}
1211 				if( xBase64Stream.is() )
1212 					bOwnBase64Stream = sal_True;
1213 			}
1214 			if( bOwnBase64Stream && xBase64Stream.is() )
1215 			{
1216 				OUString sChars;
1217 				if( sBase64CharsLeft )
1218 				{
1219 					sChars = sBase64CharsLeft;
1220 					sChars += sTrimmedChars;
1221 					sBase64CharsLeft = OUString();
1222 				}
1223 				else
1224 				{
1225 					sChars = sTrimmedChars;
1226 				}
1227 				Sequence< sal_Int8 > aBuffer( (sChars.getLength() / 4) * 3 );
1228 				sal_Int32 nCharsDecoded =
1229 					GetImport().GetMM100UnitConverter().
1230 						decodeBase64SomeChars( aBuffer, sChars );
1231 				xBase64Stream->writeBytes( aBuffer );
1232 				if( nCharsDecoded != sChars.getLength() )
1233 					sBase64CharsLeft = sChars.copy( nCharsDecoded );
1234 			}
1235 		}
1236 	}
1237 }
1238 
1239 void XMLTextFrameContext_Impl::SetHyperlink( const OUString& rHRef,
1240 					   const OUString& rName,
1241 					   const OUString& rTargetFrameName,
1242 					   sal_Bool bMap )
1243 {
1244     static ::rtl::OUString s_HyperLinkURL(
1245         RTL_CONSTASCII_USTRINGPARAM("HyperLinkURL"));
1246     static ::rtl::OUString s_HyperLinkName(
1247         RTL_CONSTASCII_USTRINGPARAM("HyperLinkName"));
1248     static ::rtl::OUString s_HyperLinkTarget(
1249         RTL_CONSTASCII_USTRINGPARAM("HyperLinkTarget"));
1250     static ::rtl::OUString s_ServerMap(
1251         RTL_CONSTASCII_USTRINGPARAM("ServerMap"));
1252 	if( !xPropSet.is() )
1253 		return;
1254 
1255 	UniReference< XMLTextImportHelper > xTxtImp = GetImport().GetTextImport();
1256 	Reference < XPropertySetInfo > xPropSetInfo =
1257 		xPropSet->getPropertySetInfo();
1258 	if( !xPropSetInfo.is() ||
1259         !xPropSetInfo->hasPropertyByName(s_HyperLinkURL))
1260 		return;
1261 
1262 	Any aAny;
1263 	aAny <<= rHRef;
1264     xPropSet->setPropertyValue( s_HyperLinkURL, aAny );
1265 
1266     if (xPropSetInfo->hasPropertyByName(s_HyperLinkName))
1267 	{
1268 		aAny <<= rName;
1269         xPropSet->setPropertyValue(s_HyperLinkName, aAny);
1270 	}
1271 
1272     if (xPropSetInfo->hasPropertyByName(s_HyperLinkTarget))
1273 	{
1274 		aAny <<= rTargetFrameName;
1275         xPropSet->setPropertyValue( s_HyperLinkTarget, aAny );
1276 	}
1277 
1278     if (xPropSetInfo->hasPropertyByName(s_ServerMap))
1279 	{
1280 		aAny.setValue( &bMap, ::getBooleanCppuType() );
1281         xPropSet->setPropertyValue(s_ServerMap, aAny);
1282 	}
1283 }
1284 
1285 // --> OD 2009-07-22 #i73249#
1286 void XMLTextFrameContext_Impl::SetTitle( const OUString& rTitle )
1287 {
1288     if ( xPropSet.is() )
1289     {
1290         Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1291         if( xPropSetInfo->hasPropertyByName( sTitle ) )
1292         {
1293             xPropSet->setPropertyValue( sTitle, makeAny( rTitle ) );
1294         }
1295     }
1296 }
1297 
1298 void XMLTextFrameContext_Impl::SetDesc( const OUString& rDesc )
1299 {
1300 	if ( xPropSet.is() )
1301 	{
1302         Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1303         if( xPropSetInfo->hasPropertyByName( sDescription ) )
1304 		{
1305             xPropSet->setPropertyValue( sDescription, makeAny( rDesc ) );
1306 		}
1307 	}
1308 }
1309 // <--
1310 
1311 //-----------------------------------------------------------------------------------------------------
1312 
1313 TYPEINIT1( XMLTextFrameContext, SvXMLImportContext );
1314 
1315 sal_Bool XMLTextFrameContext::CreateIfNotThere()
1316 {
1317 	sal_Bool bRet = sal_False;
1318 	SvXMLImportContext *pContext = &m_xImplContext;
1319 	XMLTextFrameContext_Impl *pImpl = PTR_CAST( XMLTextFrameContext_Impl, pContext );
1320 	if( pImpl )
1321 		bRet = pImpl->CreateIfNotThere();
1322 
1323 	return bRet;
1324 }
1325 
1326 sal_Bool XMLTextFrameContext::CreateIfNotThere( ::com::sun::star::uno::Reference <
1327 		::com::sun::star::beans::XPropertySet >& rPropSet )
1328 {
1329 	SvXMLImportContext *pContext = &m_xImplContext;
1330 	XMLTextFrameContext_Impl *pImpl = PTR_CAST( XMLTextFrameContext_Impl, pContext );
1331 	if( pImpl )
1332 	{
1333 		if( pImpl->CreateIfNotThere() )
1334 			rPropSet = pImpl->GetPropSet();
1335 	}
1336 
1337 	return rPropSet.is();
1338 }
1339 
1340 XMLTextFrameContext::XMLTextFrameContext(
1341 		SvXMLImport& rImport,
1342 		sal_uInt16 nPrfx, const OUString& rLName,
1343 		const Reference< XAttributeList > & xAttrList,
1344 		TextContentAnchorType eATyp )
1345 :	SvXMLImportContext( rImport, nPrfx, rLName )
1346 ,	m_xAttrList( new SvXMLAttributeList( xAttrList ) )
1347 ,	m_pHyperlink( 0 )
1348 // --> OD 2009-07-22 #i73249#
1349 ,   m_sTitle()
1350 ,   m_sDesc()
1351 // <--
1352 ,	m_eDefaultAnchorType( eATyp )
1353     // --> OD 2006-03-10 #i51726#
1354 ,   m_HasAutomaticStyleWithoutParentStyle( sal_False )
1355     // <--
1356 ,	m_bSupportsReplacement( sal_False )
1357 {
1358 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1359 	for( sal_Int16 i=0; i < nAttrCount; i++ )
1360 	{
1361 		const OUString& rAttrName = xAttrList->getNameByIndex( i );
1362 
1363 		OUString aLocalName;
1364 		sal_uInt16 nPrefix =
1365 			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
1366         // --> OD 2006-03-10 #i51726#
1367         // New distinguish attribute between Writer objects and Draw objects is:
1368         // Draw objects have an automatic style without a parent style
1369         if ( XML_NAMESPACE_DRAW == nPrefix &&
1370              IsXMLToken( aLocalName, XML_STYLE_NAME ) )
1371 		{
1372             OUString aStyleName = xAttrList->getValueByIndex( i );
1373             if( aStyleName.getLength() )
1374             {
1375                 UniReference < XMLTextImportHelper > xTxtImport =
1376                                                     GetImport().GetTextImport();
1377                 XMLPropStyleContext* pStyle( 0L );
1378                 pStyle = xTxtImport->FindAutoFrameStyle( aStyleName );
1379                 if ( pStyle && !pStyle->GetParentName().getLength() )
1380                 {
1381                     m_HasAutomaticStyleWithoutParentStyle = sal_True;
1382                 }
1383             }
1384         }
1385         // <--
1386         else if ( XML_NAMESPACE_TEXT == nPrefix &&
1387                   IsXMLToken( aLocalName, XML_ANCHOR_TYPE ) )
1388 		{
1389 			TextContentAnchorType eNew;
1390 			if( XMLAnchorTypePropHdl::convert( xAttrList->getValueByIndex(i),
1391 						eNew ) &&
1392 				( TextContentAnchorType_AT_PARAGRAPH == eNew ||
1393 				  TextContentAnchorType_AT_CHARACTER == eNew ||
1394 				  TextContentAnchorType_AS_CHARACTER == eNew ||
1395 				  TextContentAnchorType_AT_PAGE == eNew) )
1396 				m_eDefaultAnchorType = eNew;
1397 		}
1398 	}
1399 }
1400 
1401 XMLTextFrameContext::~XMLTextFrameContext()
1402 {
1403 	delete m_pHyperlink;
1404 }
1405 
1406 void XMLTextFrameContext::EndElement()
1407 {
1408 	SvXMLImportContext *pContext = &m_xImplContext;
1409 	XMLTextFrameContext_Impl *pImpl = PTR_CAST( XMLTextFrameContext_Impl, pContext );
1410 	if( pImpl )
1411 	{
1412 		pImpl->CreateIfNotThere();
1413 
1414         // --> OD 2009-07-22 #i73249#
1415 //        // alternative text
1416 //        if( m_sDesc.getLength() )
1417 //            pImpl->SetDesc( m_sDesc );
1418         // svg:title
1419         if( m_sTitle.getLength() )
1420         {
1421             pImpl->SetTitle( m_sTitle );
1422         }
1423         if( m_sDesc.getLength() )
1424         {
1425             pImpl->SetDesc( m_sDesc );
1426         }
1427         // <--
1428 
1429 		if( m_pHyperlink )
1430 		{
1431 			pImpl->SetHyperlink( m_pHyperlink->GetHRef(), m_pHyperlink->GetName(),
1432 						  m_pHyperlink->GetTargetFrameName(), m_pHyperlink->GetMap() );
1433 			delete m_pHyperlink;
1434 			m_pHyperlink = 0;
1435 		}
1436 
1437 	}
1438 }
1439 
1440 SvXMLImportContext *XMLTextFrameContext::CreateChildContext(
1441 		sal_uInt16 p_nPrefix,
1442 		const OUString& rLocalName,
1443 		const Reference< XAttributeList > & xAttrList )
1444 {
1445 	SvXMLImportContext *pContext = 0;
1446 
1447 	if( !m_xImplContext.Is() )
1448 	{
1449 		// no child exists
1450 		if( XML_NAMESPACE_DRAW == p_nPrefix )
1451 		{
1452 			sal_uInt16 nFrameType = USHRT_MAX;
1453 			if( IsXMLToken( rLocalName, XML_TEXT_BOX ) )
1454 				nFrameType = XML_TEXT_FRAME_TEXTBOX;
1455 			else if( IsXMLToken( rLocalName, XML_IMAGE ) )
1456 				nFrameType = XML_TEXT_FRAME_GRAPHIC;
1457 			else if( IsXMLToken( rLocalName, XML_OBJECT ) )
1458 				nFrameType = XML_TEXT_FRAME_OBJECT;
1459 			else if( IsXMLToken( rLocalName, XML_OBJECT_OLE ) )
1460 				nFrameType = XML_TEXT_FRAME_OBJECT_OLE;
1461 			else if( IsXMLToken( rLocalName, XML_APPLET) )
1462 				nFrameType = XML_TEXT_FRAME_APPLET;
1463 			else if( IsXMLToken( rLocalName, XML_PLUGIN ) )
1464 				nFrameType = XML_TEXT_FRAME_PLUGIN;
1465 			else if( IsXMLToken( rLocalName, XML_FLOATING_FRAME ) )
1466 				nFrameType = XML_TEXT_FRAME_FLOATING_FRAME;
1467 
1468 			if( USHRT_MAX != nFrameType )
1469 			{
1470                 // --> OD 2006-03-10 #i51726#
1471                 if ( ( XML_TEXT_FRAME_TEXTBOX == nFrameType ||
1472                        XML_TEXT_FRAME_GRAPHIC == nFrameType ) &&
1473                      m_HasAutomaticStyleWithoutParentStyle )
1474                 // <--
1475 				{
1476 					Reference < XShapes > xShapes;
1477 					pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
1478 									GetImport(), p_nPrefix, rLocalName, xAttrList, xShapes, m_xAttrList );
1479 				}
1480 				else if( XML_TEXT_FRAME_PLUGIN == nFrameType )
1481 				{
1482 				    bool bMedia = false;
1483 
1484 				    // check, if we have a media object
1485 	                for( sal_Int16 n = 0, nAttrCount = ( xAttrList.is() ? xAttrList->getLength() : 0 ); n < nAttrCount; ++n )
1486 	                {
1487 		                OUString 	aLocalName;
1488 		                sal_uInt16 	nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( n ), &aLocalName );
1489 
1490 		                if( nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( aLocalName, XML_MIME_TYPE ) )
1491 		                {
1492 			                if( 0 == xAttrList->getValueByIndex( n ).compareToAscii( "application/vnd.sun.star.media" ) )
1493 				                bMedia = true;
1494 
1495 			                // leave this loop
1496 			                n = nAttrCount - 1;
1497 		                }
1498 	                }
1499 
1500 	                if( bMedia )
1501 	                {
1502 	                    Reference < XShapes > xShapes;
1503 					    pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
1504 									    GetImport(), p_nPrefix, rLocalName, xAttrList, xShapes, m_xAttrList );
1505 					}
1506 				}
1507 				else if( XML_TEXT_FRAME_OBJECT == nFrameType ||
1508 						 XML_TEXT_FRAME_OBJECT_OLE == nFrameType )
1509 				{
1510 					m_bSupportsReplacement = sal_True;
1511 				}
1512 
1513 				if( !pContext )
1514 				{
1515 
1516 					pContext = new XMLTextFrameContext_Impl( GetImport(), p_nPrefix,
1517 														rLocalName, xAttrList,
1518 														m_eDefaultAnchorType,
1519 														nFrameType,
1520 														m_xAttrList	);
1521 				}
1522 
1523 				m_xImplContext = pContext;
1524 			}
1525 		}
1526 	}
1527 	else if( m_bSupportsReplacement && !m_xReplImplContext &&
1528 			 XML_NAMESPACE_DRAW == p_nPrefix &&
1529 			 IsXMLToken( rLocalName, XML_IMAGE ) )
1530 	{
1531 		// read replacement image
1532 		Reference < XPropertySet > xPropSet;
1533 		if( CreateIfNotThere( xPropSet ) )
1534 		{
1535 			pContext = new XMLReplacementImageContext( GetImport(),
1536 								p_nPrefix, rLocalName, xAttrList, xPropSet );
1537 			m_xReplImplContext = pContext;
1538 		}
1539 	}
1540 	else if( m_xImplContext->ISA( XMLTextFrameContext_Impl ) )
1541 	{
1542 		// the child is a writer frame
1543 		if( XML_NAMESPACE_SVG == p_nPrefix )
1544 		{
1545             // --> OD 2009-07-22 #i73249#
1546 //            bool bOld = SvXMLImport::OOo_2x >= GetImport().getGeneratorVersion();
1547 //            if( IsXMLToken( rLocalName, bOld ? XML_DESC : XML_TITLE ) )
1548 //                pContext = new XMLTextFrameDescContext_Impl( GetImport(), p_nPrefix, rLocalName,
1549 //                                                         xAttrList, m_sDesc );
1550             const bool bOld = SvXMLImport::OOo_2x >= GetImport().getGeneratorVersion();
1551             if ( bOld )
1552             {
1553                 if ( IsXMLToken( rLocalName, XML_DESC ) )
1554                 {
1555                     pContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1556                                                                         p_nPrefix,
1557                                                                         rLocalName,
1558                                                                         m_sTitle );
1559                 }
1560             }
1561             else
1562             {
1563                 if( IsXMLToken( rLocalName, XML_TITLE ) )
1564                 {
1565                     pContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1566                                                                         p_nPrefix,
1567                                                                         rLocalName,
1568                                                                         m_sTitle );
1569                 }
1570                 else if ( IsXMLToken( rLocalName, XML_DESC ) )
1571                 {
1572                     pContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1573                                                                         p_nPrefix,
1574                                                                         rLocalName,
1575                                                                         m_sDesc );
1576                 }
1577             }
1578             // <--
1579 		}
1580 		else if( XML_NAMESPACE_DRAW == p_nPrefix )
1581 		{
1582 			Reference < XPropertySet > xPropSet;
1583 			if( IsXMLToken( rLocalName, XML_CONTOUR_POLYGON ) )
1584 			{
1585 				if( CreateIfNotThere( xPropSet ) )
1586 					pContext = new XMLTextFrameContourContext_Impl( GetImport(), p_nPrefix, rLocalName,
1587 												  xAttrList, xPropSet, sal_False );
1588 			}
1589 			else if( IsXMLToken( rLocalName, XML_CONTOUR_PATH ) )
1590 			{
1591 				if( CreateIfNotThere( xPropSet ) )
1592 					pContext = new XMLTextFrameContourContext_Impl( GetImport(), p_nPrefix, rLocalName,
1593 												  xAttrList, xPropSet, sal_True );
1594 			}
1595 			else if( IsXMLToken( rLocalName, XML_IMAGE_MAP ) )
1596 			{
1597 				if( CreateIfNotThere( xPropSet ) )
1598 					pContext = new XMLImageMapContext( GetImport(), p_nPrefix, rLocalName, xPropSet );
1599 			}
1600 		}
1601 		else if( (XML_NAMESPACE_OFFICE == p_nPrefix) && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) )
1602 		{
1603 			// do we still have the frame object?
1604 			Reference < XPropertySet > xPropSet;
1605 			if( CreateIfNotThere( xPropSet ) )
1606 			{
1607 				// is it an event supplier?
1608 				Reference<XEventsSupplier> xEventsSupplier(xPropSet, UNO_QUERY);
1609 				if (xEventsSupplier.is())
1610 				{
1611 					// OK, we have the events, so create the context
1612 					pContext = new XMLEventsImportContext(GetImport(), p_nPrefix,
1613 													  rLocalName, xEventsSupplier);
1614 				}
1615 			}
1616 		}
1617 	}
1618 	else if( p_nPrefix == XML_NAMESPACE_SVG &&	// #i68101#
1619 				(IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) )
1620 	{
1621 		pContext = m_xImplContext->CreateChildContext( p_nPrefix, rLocalName, xAttrList );
1622 	}
1623 	else
1624 	{
1625 		// the child is a drawing shape
1626 		pContext = GetImport().GetShapeImport()->CreateFrameChildContext(
1627 									&m_xImplContext, p_nPrefix, rLocalName, xAttrList );
1628 	}
1629 
1630 	if( !pContext )
1631 		pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
1632 
1633 	return pContext;
1634 }
1635 
1636 void XMLTextFrameContext::SetHyperlink( const OUString& rHRef,
1637 					   const OUString& rName,
1638 					   const OUString& rTargetFrameName,
1639 					   sal_Bool bMap )
1640 {
1641 	OSL_ENSURE( !m_pHyperlink, "recursive SetHyperlink call" );
1642 	delete m_pHyperlink;
1643 	m_pHyperlink = new XMLTextFrameContextHyperlink_Impl(
1644 				rHRef, rName, rTargetFrameName, bMap );
1645 }
1646 
1647 TextContentAnchorType XMLTextFrameContext::GetAnchorType() const
1648 {
1649 	SvXMLImportContext *pContext = &m_xImplContext;
1650 	XMLTextFrameContext_Impl *pImpl = PTR_CAST( XMLTextFrameContext_Impl, pContext );
1651 	if( pImpl )
1652 		return pImpl->GetAnchorType();
1653 	else
1654 		return m_eDefaultAnchorType;
1655 }
1656 
1657 Reference < XTextContent > XMLTextFrameContext::GetTextContent() const
1658 {
1659 	Reference < XTextContent > xTxtCntnt;
1660 	SvXMLImportContext *pContext = &m_xImplContext;
1661 	XMLTextFrameContext_Impl *pImpl = PTR_CAST( XMLTextFrameContext_Impl, pContext );
1662 	if( pImpl )
1663 		xTxtCntnt.set( pImpl->GetPropSet(), UNO_QUERY );
1664 
1665 	return xTxtCntnt;
1666 }
1667 
1668 // --> OD 2004-08-24 #33242#
1669 Reference < XShape > XMLTextFrameContext::GetShape() const
1670 {
1671     Reference < XShape > xShape;
1672     SvXMLImportContext* pContext = &m_xImplContext;
1673     SvXMLShapeContext* pImpl = PTR_CAST( SvXMLShapeContext, pContext );
1674     if ( pImpl )
1675     {
1676         xShape = pImpl->getShape();
1677     }
1678 
1679     return xShape;
1680 }
1681 // <--
1682