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 "unointerfacetouniqueidentifiermapper.hxx"
31 #include <com/sun/star/text/XText.hpp>
32 #include <com/sun/star/container/XNamed.hpp>
33 #include <com/sun/star/container/XEnumerationAccess.hpp>
34 #include <com/sun/star/drawing/CircleKind.hpp>
35 #include <com/sun/star/drawing/ConnectorType.hpp>
36 #include <com/sun/star/drawing/XControlShape.hpp>
37 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
38 #include <com/sun/star/document/XEventsSupplier.hpp>
39 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
40 #include <com/sun/star/media/ZoomLevel.hpp>
41 #include "anim.hxx"
42 
43 #ifndef _XMLOFF_SHAPEEXPORT_HXX
44 #include <xmloff/shapeexport.hxx>
45 #endif
46 #include "sdpropls.hxx"
47 #include <tools/debug.hxx>
48 #include <tools/urlobj.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <xmloff/xmlexp.hxx>
51 #include <xmloff/xmluconv.hxx>
52 #include "XMLImageMapExport.hxx"
53 #include "xexptran.hxx"
54 #include <tools/gen.hxx>		// FRound
55 #include <xmloff/xmltoken.hxx>
56 #include <xmloff/nmspmap.hxx>
57 
58 #include "xmloff/xmlnmspe.hxx"
59 #include <basegfx/matrix/b2dhommatrix.hxx>
60 #include <basegfx/tuple/b2dtuple.hxx>
61 
62 using ::rtl::OUString;
63 using ::rtl::OUStringBuffer;
64 
65 using namespace ::com::sun::star;
66 using namespace ::xmloff::token;
67 
68 
69 //////////////////////////////////////////////////////////////////////////////
70 
71 void XMLShapeExport::ImpExportNewTrans(const uno::Reference< beans::XPropertySet >& xPropSet,
72 	sal_Int32 nFeatures, awt::Point* pRefPoint)
73 {
74 	// get matrix
75 	::basegfx::B2DHomMatrix aMatrix;
76 	ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
77 
78 	// decompose and correct abour pRefPoint
79 	::basegfx::B2DTuple aTRScale;
80 	double fTRShear(0.0);
81 	double fTRRotate(0.0);
82 	::basegfx::B2DTuple aTRTranslate;
83 	ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
84 
85 	// use features and write
86 	ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
87 }
88 
89 void XMLShapeExport::ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix& rMatrix,
90 	const uno::Reference< beans::XPropertySet >& xPropSet)
91 {
92     // --> OD 2004-08-09 #i28749# - Get <TransformationInHoriL2R>, if it exist
93     // and if the document is exported into the OpenOffice.org file format.
94     // This property only exists at service com::sun::star::text::Shape - the
95     // Writer UNO service for shapes.
96     // This code is needed, because the positioning attributes in the
97     // OpenOffice.org file format are given in horizontal left-to-right layout
98     // regardless the layout direction the shape is in. In the OASIS Open Office
99     // file format the positioning attributes are correctly given in the layout
100     // direction the shape is in. Thus, this code provides the conversion from
101     // the OASIS Open Office file format to the OpenOffice.org file format.
102     uno::Any aAny;
103     if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 &&
104          xPropSet->getPropertySetInfo()->hasPropertyByName(
105             OUString(RTL_CONSTASCII_USTRINGPARAM("TransformationInHoriL2R"))) )
106     {
107         aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("TransformationInHoriL2R")));
108     }
109     else
110     {
111         aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Transformation")));
112     }
113     // <--
114 	drawing::HomogenMatrix3 aMatrix;
115 	aAny >>= aMatrix;
116 
117 	rMatrix.set(0, 0, aMatrix.Line1.Column1);
118 	rMatrix.set(0, 1, aMatrix.Line1.Column2);
119 	rMatrix.set(0, 2, aMatrix.Line1.Column3);
120 	rMatrix.set(1, 0, aMatrix.Line2.Column1);
121 	rMatrix.set(1, 1, aMatrix.Line2.Column2);
122 	rMatrix.set(1, 2, aMatrix.Line2.Column3);
123 	rMatrix.set(2, 0, aMatrix.Line3.Column1);
124 	rMatrix.set(2, 1, aMatrix.Line3.Column2);
125 	rMatrix.set(2, 2, aMatrix.Line3.Column3);
126 }
127 
128 void XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix& rMatrix, ::basegfx::B2DTuple& rTRScale,
129 	double& fTRShear, double& fTRRotate, ::basegfx::B2DTuple& rTRTranslate, com::sun::star::awt::Point* pRefPoint)
130 {
131 	// decompose matrix
132 	rMatrix.decompose(rTRScale, rTRTranslate, fTRRotate, fTRShear);
133 
134 	// correct translation about pRefPoint
135 	if(pRefPoint)
136 	{
137 		rTRTranslate -= ::basegfx::B2DTuple(pRefPoint->X, pRefPoint->Y);
138 	}
139 }
140 
141 void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple& rTRScale, double fTRShear,
142 	double fTRRotate, ::basegfx::B2DTuple& rTRTranslate, const sal_Int32 nFeatures)
143 {
144 	// allways write Size (rTRScale) since this statement carries the union
145 	// of the object
146 	OUString aStr;
147 	OUStringBuffer sStringBuffer;
148 	::basegfx::B2DTuple aTRScale(rTRScale);
149 
150 	// svg: width
151 	if(!(nFeatures & SEF_EXPORT_WIDTH))
152 	{
153 		aTRScale.setX(1.0);
154 	}
155 	else
156 	{
157 		if( aTRScale.getX() > 0.0 )
158 			aTRScale.setX(aTRScale.getX() - 1.0);
159 		else if( aTRScale.getX() < 0.0 )
160 			aTRScale.setX(aTRScale.getX() + 1.0);
161 	}
162 
163 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(aTRScale.getX()));
164 	aStr = sStringBuffer.makeStringAndClear();
165 	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr);
166 
167 	// svg: height
168 	if(!(nFeatures & SEF_EXPORT_HEIGHT))
169 	{
170 		aTRScale.setY(1.0);
171 	}
172 	else
173 	{
174 		if( aTRScale.getY() > 0.0 )
175 			aTRScale.setY(aTRScale.getY() - 1.0);
176 		else if( aTRScale.getY() < 0.0 )
177 			aTRScale.setY(aTRScale.getY() + 1.0);
178 	}
179 
180 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(aTRScale.getY()));
181 	aStr = sStringBuffer.makeStringAndClear();
182 	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr);
183 
184 	// decide if transformation is neccessary
185 	sal_Bool bTransformationIsNeccessary(fTRShear != 0.0 || fTRRotate != 0.0);
186 
187 	if(bTransformationIsNeccessary)
188 	{
189 		// write transformation, but WITHOUT scale which is exported as size above
190 		SdXMLImExTransform2D aTransform;
191 
192 		aTransform.AddSkewX(atan(fTRShear));
193 
194         // #i78696#
195         // fTRRotate is mathematically correct, but due to the error
196         // we export/import it mirrored. Since the API implementation is fixed and
197         // uses the correctly oriented angle, it is necessary for compatibility to
198         // mirror the angle here to stay at the old behaviour. There is a follow-up
199         // task (#i78698#) to fix this in the next ODF FileFormat version
200 		aTransform.AddRotate(-fTRRotate);
201 
202         aTransform.AddTranslate(rTRTranslate);
203 
204 		// does transformation need to be exported?
205 		if(aTransform.NeedsAction())
206 			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
207 	}
208 	else
209 	{
210 		// no shear, no rotate; just add object position to export and we are done
211 		if(nFeatures & SEF_EXPORT_X)
212 		{
213 			// svg: x
214 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(rTRTranslate.getX()));
215 			aStr = sStringBuffer.makeStringAndClear();
216 			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr);
217 		}
218 
219 		if(nFeatures & SEF_EXPORT_Y)
220 		{
221 			// svg: y
222 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, FRound(rTRTranslate.getY()));
223 			aStr = sStringBuffer.makeStringAndClear();
224 			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr);
225 		}
226 	}
227 }
228 
229 //////////////////////////////////////////////////////////////////////////////
230 
231 sal_Bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference< beans::XPropertySet >& xPropSet, const rtl::OUString& rClass )
232 {
233 	sal_Bool bIsEmpty = sal_False;
234 
235 	OUStringBuffer sStringBuffer;
236 
237 	// write presentation class entry
238 	mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS, rClass);
239 
240 	if( xPropSet.is() )
241 	{
242 		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
243 
244 		sal_Bool bTemp = false;
245 
246 		// is empty pes shape?
247 		if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject"))))
248 		{
249 			xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject"))) >>= bIsEmpty;
250 			if( bIsEmpty )
251 				mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, XML_TRUE);
252 		}
253 
254 		// is user-transformed?
255 		if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent"))))
256 		{
257 			xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("IsPlaceholderDependent"))) >>= bTemp;
258 			if(!bTemp)
259 				mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_USER_TRANSFORMED, XML_TRUE);
260 		}
261 	}
262 
263 	return bIsEmpty;
264 }
265 
266 //////////////////////////////////////////////////////////////////////////////
267 
268 void XMLShapeExport::ImpExportText( const uno::Reference< drawing::XShape >& xShape )
269 {
270 	uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
271 	if( xText.is() )
272 	{
273 		uno::Reference< container::XEnumerationAccess > xEnumAccess( xShape, uno::UNO_QUERY );
274 		if( xEnumAccess.is() && xEnumAccess->hasElements() )
275 			mrExport.GetTextParagraphExport()->exportText( xText );
276 	}
277 }
278 
279 //////////////////////////////////////////////////////////////////////////////
280 #include <com/sun/star/presentation/ClickAction.hpp>
281 #include <com/sun/star/presentation/AnimationSpeed.hpp>
282 
283 namespace {
284 
285 const sal_Int32 FOUND_CLICKACTION       = 0x00000001;
286 const sal_Int32 FOUND_BOOKMARK          = 0x00000002;
287 const sal_Int32 FOUND_EFFECT            = 0x00000004;
288 const sal_Int32 FOUND_PLAYFULL          = 0x00000008;
289 const sal_Int32 FOUND_VERB              = 0x00000010;
290 const sal_Int32 FOUND_SOUNDURL          = 0x00000020;
291 const sal_Int32 FOUND_SPEED             = 0x00000040;
292 const sal_Int32 FOUND_CLICKEVENTTYPE    = 0x00000080;
293 const sal_Int32 FOUND_MACRO             = 0x00000100;
294 const sal_Int32 FOUND_LIBRARY           = 0x00000200;
295 const sal_Int32 FOUND_ACTIONEVENTTYPE   = 0x00000400;
296 #ifdef ISSUE66550_HLINK_FOR_SHAPES
297 const sal_Int32 FOUND_URL               = 0x00000800;
298 #endif
299 
300 } // namespace
301 
302 void XMLShapeExport::ImpExportEvents( const uno::Reference< drawing::XShape >& xShape )
303 {
304     uno::Reference< document::XEventsSupplier > xEventsSupplier( xShape, uno::UNO_QUERY );
305     if( !xEventsSupplier.is() )
306         return;
307 
308     uno::Reference< container::XNameAccess > xEvents( xEventsSupplier->getEvents(), uno::UNO_QUERY );
309     DBG_ASSERT( xEvents.is(), "XEventsSupplier::getEvents() returned NULL" );
310     if( !xEvents.is() )
311         return;
312 
313     sal_Int32 nFound = 0;
314 
315     // extract properties from "OnClick" event --------------------------------
316 
317     OUString aClickEventType;
318     presentation::ClickAction eClickAction = presentation::ClickAction_NONE;
319     presentation::AnimationEffect eEffect = presentation::AnimationEffect_NONE;
320     presentation::AnimationSpeed eSpeed = presentation::AnimationSpeed_SLOW;
321     OUString aStrSoundURL;
322     sal_Bool bPlayFull = false;
323     sal_Int32 nVerb = 0;
324     OUString aStrMacro;
325     OUString aStrLibrary;
326     OUString aStrBookmark;
327 
328     uno::Sequence< beans::PropertyValue > aClickProperties;
329     if( xEvents->hasByName( msOnClick ) && (xEvents->getByName( msOnClick ) >>= aClickProperties) )
330     {
331         const beans::PropertyValue* pProperty = aClickProperties.getConstArray();
332         const beans::PropertyValue* pPropertyEnd = pProperty + aClickProperties.getLength();
333         for( ; pProperty != pPropertyEnd; ++pProperty )
334         {
335             if( ( ( nFound & FOUND_CLICKEVENTTYPE ) == 0 ) && pProperty->Name == msEventType )
336             {
337                 if( pProperty->Value >>= aClickEventType )
338                     nFound |= FOUND_CLICKEVENTTYPE;
339             }
340             else if( ( ( nFound & FOUND_CLICKACTION ) == 0 ) && pProperty->Name == msClickAction )
341             {
342                 if( pProperty->Value >>= eClickAction )
343                     nFound |= FOUND_CLICKACTION;
344             }
345             else if( ( ( nFound & FOUND_MACRO ) == 0 ) && ( pProperty->Name == msMacroName || pProperty->Name == msScript ) )
346             {
347                 if( pProperty->Value >>= aStrMacro )
348                     nFound |= FOUND_MACRO;
349             }
350             else if( ( ( nFound & FOUND_LIBRARY ) == 0 ) && pProperty->Name == msLibrary )
351             {
352                 if( pProperty->Value >>= aStrLibrary )
353                     nFound |= FOUND_LIBRARY;
354             }
355             else if( ( ( nFound & FOUND_EFFECT ) == 0 ) && pProperty->Name == msEffect )
356             {
357                 if( pProperty->Value >>= eEffect )
358                     nFound |= FOUND_EFFECT;
359             }
360             else if( ( ( nFound & FOUND_BOOKMARK ) == 0 ) && pProperty->Name == msBookmark )
361             {
362                 if( pProperty->Value >>= aStrBookmark )
363                     nFound |= FOUND_BOOKMARK;
364             }
365             else if( ( ( nFound & FOUND_SPEED ) == 0 ) && pProperty->Name == msSpeed )
366             {
367                 if( pProperty->Value >>= eSpeed )
368                     nFound |= FOUND_SPEED;
369             }
370             else if( ( ( nFound & FOUND_SOUNDURL ) == 0 ) && pProperty->Name == msSoundURL )
371             {
372                 if( pProperty->Value >>= aStrSoundURL )
373                     nFound |= FOUND_SOUNDURL;
374             }
375             else if( ( ( nFound & FOUND_PLAYFULL ) == 0 ) && pProperty->Name == msPlayFull )
376             {
377                 if( pProperty->Value >>= bPlayFull )
378                     nFound |= FOUND_PLAYFULL;
379             }
380             else if( ( ( nFound & FOUND_VERB ) == 0 ) && pProperty->Name == msVerb )
381             {
382                 if( pProperty->Value >>= nVerb )
383                     nFound |= FOUND_VERB;
384             }
385         }
386     }
387 
388 #ifdef ISSUE66550_HLINK_FOR_SHAPES
389     // extract properties from "OnAction" event -------------------------------
390 
391     OUString aActionEventType;
392     OUString aHyperURL;
393 
394     uno::Sequence< beans::PropertyValue > aActionProperties;
395     if( xEvents->hasByName( msOnAction ) && (xEvents->getByName( msOnAction ) >>= aActionProperties) )
396     {
397         const beans::PropertyValue* pProperty = aActionProperties.getConstArray();
398         const beans::PropertyValue* pPropertyEnd = pProperty + aActionProperties.getLength();
399         for( ; pProperty != pPropertyEnd; ++pProperty )
400         {
401             if( ( ( nFound & FOUND_ACTIONEVENTTYPE ) == 0 ) && pProperty->Name == msEventType )
402             {
403                 if( pProperty->Value >>= aActionEventType )
404                     nFound |= FOUND_ACTIONEVENTTYPE;
405             }
406             else if( ( ( nFound & FOUND_URL ) == 0 ) && ( pProperty->Name == msURL  ) )
407             {
408                 if( pProperty->Value >>= aHyperURL )
409                     nFound |= FOUND_URL;
410             }
411         }
412     }
413 #endif
414 
415     // create the XML elements
416 
417     if( aClickEventType == msPresentation )
418     {
419         if( ((nFound & FOUND_CLICKACTION) == 0) || (eClickAction == presentation::ClickAction_NONE) )
420             return;
421 
422         SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, sal_True, sal_True);
423 
424         enum XMLTokenEnum eStrAction;
425 
426         switch( eClickAction )
427         {
428             case presentation::ClickAction_PREVPAGE:        eStrAction = XML_PREVIOUS_PAGE; break;
429             case presentation::ClickAction_NEXTPAGE:        eStrAction = XML_NEXT_PAGE; break;
430             case presentation::ClickAction_FIRSTPAGE:       eStrAction = XML_FIRST_PAGE; break;
431             case presentation::ClickAction_LASTPAGE:        eStrAction = XML_LAST_PAGE; break;
432             case presentation::ClickAction_INVISIBLE:       eStrAction = XML_HIDE; break;
433             case presentation::ClickAction_STOPPRESENTATION:eStrAction = XML_STOP; break;
434             case presentation::ClickAction_PROGRAM:         eStrAction = XML_EXECUTE; break;
435             case presentation::ClickAction_BOOKMARK:        eStrAction = XML_SHOW; break;
436             case presentation::ClickAction_DOCUMENT:        eStrAction = XML_SHOW; break;
437             case presentation::ClickAction_MACRO:           eStrAction = XML_EXECUTE_MACRO; break;
438             case presentation::ClickAction_VERB:            eStrAction = XML_VERB; break;
439             case presentation::ClickAction_VANISH:          eStrAction = XML_FADE_OUT; break;
440             case presentation::ClickAction_SOUND:           eStrAction = XML_SOUND; break;
441             default:
442                 DBG_ERROR( "unknown presentation::ClickAction found!" );
443                 eStrAction = XML_UNKNOWN;
444         }
445 
446         OUString aEventQName(
447             mrExport.GetNamespaceMap().GetQNameByKey(
448                     XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "click" ) ) ) );
449         mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
450         mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_ACTION, eStrAction );
451 
452         if( eClickAction == presentation::ClickAction_VANISH )
453         {
454             if( nFound & FOUND_EFFECT )
455             {
456                 XMLEffect eKind;
457                 XMLEffectDirection eDirection;
458                 sal_Int16 nStartScale;
459                 sal_Bool bIn;
460 
461                 SdXMLImplSetEffect( eEffect, eKind, eDirection, nStartScale, bIn );
462 
463                 if( eKind != EK_none )
464                 {
465                     SvXMLUnitConverter::convertEnum( msBuffer, eKind, aXML_AnimationEffect_EnumMap );
466                     mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_EFFECT, msBuffer.makeStringAndClear() );
467                 }
468 
469                 if( eDirection != ED_none )
470                 {
471                     SvXMLUnitConverter::convertEnum( msBuffer, eDirection, aXML_AnimationDirection_EnumMap );
472                     mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_DIRECTION, msBuffer.makeStringAndClear() );
473                 }
474 
475                 if( nStartScale != -1 )
476                 {
477                     SvXMLUnitConverter::convertPercent( msBuffer, nStartScale );
478                     mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_START_SCALE, msBuffer.makeStringAndClear() );
479                 }
480             }
481 
482             if( nFound & FOUND_SPEED && eEffect != presentation::AnimationEffect_NONE )
483             {
484                  if( eSpeed != presentation::AnimationSpeed_MEDIUM )
485                     {
486                     SvXMLUnitConverter::convertEnum( msBuffer, eSpeed, aXML_AnimationSpeed_EnumMap );
487                     mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, msBuffer.makeStringAndClear() );
488                 }
489             }
490         }
491 
492         if( eClickAction == presentation::ClickAction_PROGRAM ||
493             eClickAction == presentation::ClickAction_BOOKMARK ||
494             eClickAction == presentation::ClickAction_DOCUMENT )
495         {
496             if( eClickAction == presentation::ClickAction_BOOKMARK )
497                 msBuffer.append( sal_Unicode('#') );
498 
499             msBuffer.append( aStrBookmark );
500             mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(msBuffer.makeStringAndClear()) );
501             mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
502             mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
503             mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
504         }
505 
506         if( ( nFound & FOUND_VERB ) && eClickAction == presentation::ClickAction_VERB )
507         {
508             msBuffer.append( nVerb );
509             mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_VERB, msBuffer.makeStringAndClear());
510         }
511 
512         SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_PRESENTATION, XML_EVENT_LISTENER, sal_True, sal_True);
513 
514         if( eClickAction == presentation::ClickAction_VANISH || eClickAction == presentation::ClickAction_SOUND )
515         {
516             if( ( nFound & FOUND_SOUNDURL ) && aStrSoundURL.getLength() != 0 )
517             {
518                 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStrSoundURL) );
519                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
520                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_NEW );
521                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
522                 if( nFound & FOUND_PLAYFULL && bPlayFull )
523                     mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PLAY_FULL, XML_TRUE );
524 
525                 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_PRESENTATION, XML_SOUND, sal_True, sal_True );
526             }
527        }
528     }
529     else if( aClickEventType == msStarBasic )
530     {
531         if( nFound & FOUND_MACRO )
532         {
533             SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, sal_True, sal_True);
534 
535             mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE,
536                         mrExport.GetNamespaceMap().GetQNameByKey(
537                             XML_NAMESPACE_OOO,
538                             OUString( RTL_CONSTASCII_USTRINGPARAM(
539                                             "starbasic" ) ) ) );
540             OUString aEventQName(
541                 mrExport.GetNamespaceMap().GetQNameByKey(
542                         XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "click" ) ) ) );
543             mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
544 
545             if( nFound & FOUND_LIBRARY )
546             {
547                 OUString sLocation( GetXMLToken(
548                     (aStrLibrary.equalsIgnoreAsciiCaseAscii("StarOffice") ||
549                      aStrLibrary.equalsIgnoreAsciiCaseAscii("application") ) ? XML_APPLICATION
550                                                                        : XML_DOCUMENT ) );
551                 OUStringBuffer sTmp( sLocation.getLength() + aStrMacro.getLength() + 1 );
552                 sTmp = sLocation;
553                 sTmp.append( sal_Unicode( ':' ) );
554                 sTmp.append( aStrMacro );
555                 mrExport.AddAttribute(XML_NAMESPACE_SCRIPT, XML_MACRO_NAME,
556                                      sTmp.makeStringAndClear());
557             }
558             else
559             {
560                 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_MACRO_NAME, aStrMacro );
561             }
562 
563             SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, sal_True, sal_True);
564         }
565     }
566 #ifdef ISSUE66550_HLINK_FOR_SHAPES
567     else if( aClickEventType == msScript || aActionEventType == msAction )
568     {
569         if( nFound & ( FOUND_MACRO | FOUND_URL ) )
570 #else
571     else if( aClickEventType == msScript )
572     {
573         if( nFound & FOUND_MACRO )
574 #endif
575         {
576             SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, sal_True, sal_True);
577             if ( nFound & FOUND_MACRO )
578             {
579                 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, mrExport.GetNamespaceMap().GetQNameByKey(
580                          XML_NAMESPACE_OOO, GetXMLToken(XML_SCRIPT) ) );
581                 OUString aEventQName(
582                     mrExport.GetNamespaceMap().GetQNameByKey(
583                             XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "click" ) ) ) );
584                 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
585                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aStrMacro );
586 
587                 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, sal_True, sal_True);
588             }
589 #ifdef ISSUE66550_HLINK_FOR_SHAPES
590             if ( nFound & FOUND_URL )
591             {
592                 OUString aEventQName(
593                     mrExport.GetNamespaceMap().GetQNameByKey(
594                             XML_NAMESPACE_DOM, OUString( RTL_CONSTASCII_USTRINGPARAM( "action" ) ) ) );
595                 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
596                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aHyperURL );
597 
598                 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_PRESENTATION, XML_EVENT_LISTENER, sal_True, sal_True);
599             }
600 #endif
601         }
602     }
603 }
604 
605 //////////////////////////////////////////////////////////////////////////////
606 
607 /** #i68101# export shape Title and Description */
608 void XMLShapeExport::ImpExportDescription( const uno::Reference< drawing::XShape >& xShape )
609 {
610 	try
611 	{
612 		OUString aTitle;
613 		OUString aDescription;
614 
615 		uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
616 		xProps->getPropertyValue( OUString::createFromAscii( "Title" ) ) >>= aTitle;
617 		xProps->getPropertyValue( OUString::createFromAscii( "Description" ) ) >>= aDescription;
618 
619 		if(aTitle.getLength())
620 		{
621 			SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, sal_True, sal_False);
622 			mrExport.Characters( aTitle );
623 		}
624 
625 		if(aDescription.getLength())
626 		{
627 			SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_DESC, sal_True, sal_False );
628 			mrExport.Characters( aDescription );
629 		}
630 	}
631 	catch( uno::Exception& )
632 	{
633 		DBG_ERROR( "could not export Title and/or Description for shape!" );
634 	}
635 }
636 
637 //////////////////////////////////////////////////////////////////////////////
638 
639 void XMLShapeExport::ImpExportGroupShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
640 {
641 	uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
642 	if(xShapes.is() && xShapes->getCount())
643 	{
644 		// write group shape
645 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
646 		SvXMLElementExport aPGR(mrExport, XML_NAMESPACE_DRAW, XML_G, bCreateNewline, sal_True);
647 
648 		ImpExportDescription( xShape ); // #i68101#
649 		ImpExportEvents( xShape );
650 		ImpExportGluePoints( xShape );
651 
652 		// #89764# if export of position is supressed for group shape,
653 		// positions of contained objects should be written relative to
654 		// the upper left edge of the group.
655 		awt::Point aUpperLeft;
656 
657 		if(!(nFeatures & SEF_EXPORT_POSITION))
658 		{
659 			nFeatures |= SEF_EXPORT_POSITION;
660 			aUpperLeft = xShape->getPosition();
661 			pRefPoint = &aUpperLeft;
662 		}
663 
664 		// write members
665 		exportShapes( xShapes, nFeatures, pRefPoint );
666 	}
667 }
668 
669 //////////////////////////////////////////////////////////////////////////////
670 
671 void XMLShapeExport::ImpExportTextBoxShape(
672 	const uno::Reference< drawing::XShape >& xShape,
673 	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
674 {
675 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
676 	if(xPropSet.is())
677 	{
678 		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
679 
680 		// presentation attribute (if presentation)
681 		sal_Bool bIsPresShape(sal_False);
682 		sal_Bool bIsEmptyPresObj(sal_False);
683 		OUString aStr;
684 
685 		switch(eShapeType)
686 		{
687 			case XmlShapeTypePresSubtitleShape:
688 			{
689 				aStr = GetXMLToken(XML_PRESENTATION_SUBTITLE);
690 				bIsPresShape = sal_True;
691 				break;
692 			}
693 			case XmlShapeTypePresTitleTextShape:
694 			{
695 				aStr = GetXMLToken(XML_PRESENTATION_TITLE);
696 				bIsPresShape = sal_True;
697 				break;
698 			}
699 			case XmlShapeTypePresOutlinerShape:
700 			{
701 				aStr = GetXMLToken(XML_PRESENTATION_OUTLINE);
702 				bIsPresShape = sal_True;
703 				break;
704 			}
705 			case XmlShapeTypePresNotesShape:
706 			{
707 				aStr = GetXMLToken(XML_PRESENTATION_NOTES);
708 				bIsPresShape = sal_True;
709 				break;
710 			}
711 			case XmlShapeTypePresHeaderShape:
712 			{
713 				aStr = GetXMLToken(XML_HEADER);
714 				bIsPresShape = sal_True;
715 				break;
716 			}
717 			case XmlShapeTypePresFooterShape:
718 			{
719 				aStr = GetXMLToken(XML_FOOTER);
720 				bIsPresShape = sal_True;
721 				break;
722 			}
723 			case XmlShapeTypePresSlideNumberShape:
724 			{
725 				aStr = GetXMLToken(XML_PAGE_NUMBER);
726 				bIsPresShape = sal_True;
727 				break;
728 			}
729 			case XmlShapeTypePresDateTimeShape:
730 			{
731 				aStr = GetXMLToken(XML_DATE_TIME);
732 				bIsPresShape = sal_True;
733 				break;
734 			}
735 			default:
736 				break;
737 		}
738 
739 		// Transformation
740 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
741 
742 		if(bIsPresShape)
743 			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, aStr );
744 
745 
746 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
747 		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
748 								  XML_FRAME, bCreateNewline, sal_True );
749 
750 		// evtl. corner radius?
751 		sal_Int32 nCornerRadius(0L);
752 		xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius"))) >>= nCornerRadius;
753 		if(nCornerRadius)
754 		{
755 			OUStringBuffer sStringBuffer;
756 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nCornerRadius);
757 			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
758 		}
759 
760 		{
761 			// write text-box
762 			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_TEXT_BOX, sal_True, sal_True);
763 			if(!bIsEmptyPresObj)
764 				ImpExportText( xShape );
765 		}
766 
767 		ImpExportDescription( xShape ); // #i68101#
768 		ImpExportEvents( xShape );
769 		ImpExportGluePoints( xShape );
770 	}
771 }
772 
773 //////////////////////////////////////////////////////////////////////////////
774 
775 void XMLShapeExport::ImpExportRectangleShape(
776 	const uno::Reference< drawing::XShape >& xShape,
777 	XmlShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint)
778 {
779 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
780 	if(xPropSet.is())
781 	{
782 		// Transformation
783 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
784 
785 		// evtl. corner radius?
786 		sal_Int32 nCornerRadius(0L);
787 		xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius"))) >>= nCornerRadius;
788 		if(nCornerRadius)
789 		{
790 			OUStringBuffer sStringBuffer;
791 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nCornerRadius);
792 			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
793 		}
794 
795 		// write rectangle
796 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
797 		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_RECT, bCreateNewline, sal_True);
798 
799 		ImpExportDescription( xShape ); // #i68101#
800 		ImpExportEvents( xShape );
801 		ImpExportGluePoints( xShape );
802 		ImpExportText( xShape );
803 	}
804 }
805 
806 //////////////////////////////////////////////////////////////////////////////
807 
808 void XMLShapeExport::ImpExportLineShape(
809 	const uno::Reference< drawing::XShape >& xShape,
810 	XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
811 {
812 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
813 	if(xPropSet.is())
814 	{
815 		OUString aStr;
816 		OUStringBuffer sStringBuffer;
817 		awt::Point aStart(0,0);
818 		awt::Point aEnd(1,1);
819 
820 		// #85920# use 'Geometry' to get the points of the line
821 		// since this slot take anchor pos into account.
822 
823 		// get matrix
824 		::basegfx::B2DHomMatrix aMatrix;
825 		ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
826 
827 		// decompose and correct about pRefPoint
828 		::basegfx::B2DTuple aTRScale;
829 		double fTRShear(0.0);
830 		double fTRRotate(0.0);
831 		::basegfx::B2DTuple aTRTranslate;
832 		ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
833 
834 		// create base position
835 		awt::Point aBasePosition(FRound(aTRTranslate.getX()), FRound(aTRTranslate.getY()));
836 
837 		// get the two points
838 		uno::Any aAny(xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))));
839 		drawing::PointSequenceSequence* pSourcePolyPolygon = (drawing::PointSequenceSequence*)aAny.getValue();
840 
841 		if(pSourcePolyPolygon)
842 		{
843 		    drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray();
844 			if(pOuterSequence)
845 			{
846 		        drawing::PointSequence* pInnerSequence = pOuterSequence++;
847 				if(pInnerSequence)
848 				{
849 				    awt::Point* pArray = pInnerSequence->getArray();
850 					if(pArray)
851 					{
852 						if(pInnerSequence->getLength() > 0)
853 						{
854 							aStart = awt::Point(
855 								pArray->X + aBasePosition.X,
856 								pArray->Y + aBasePosition.Y);
857 							pArray++;
858 						}
859 
860 						if(pInnerSequence->getLength() > 1)
861 						{
862 							aEnd = awt::Point(
863 								pArray->X + aBasePosition.X,
864 								pArray->Y + aBasePosition.Y);
865 						}
866 					}
867 				}
868 			}
869 		}
870 
871 		if( nFeatures & SEF_EXPORT_X )
872 		{
873 			// svg: x1
874 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.X);
875 			aStr = sStringBuffer.makeStringAndClear();
876 			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
877 		}
878 		else
879 		{
880 			aEnd.X -= aStart.X;
881 		}
882 
883 		if( nFeatures & SEF_EXPORT_Y )
884 		{
885 			// svg: y1
886 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.Y);
887 			aStr = sStringBuffer.makeStringAndClear();
888 			mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
889 		}
890 		else
891 		{
892 			aEnd.Y -= aStart.Y;
893 		}
894 
895 		// svg: x2
896 		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.X);
897 		aStr = sStringBuffer.makeStringAndClear();
898 		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
899 
900 		// svg: y2
901 		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.Y);
902 		aStr = sStringBuffer.makeStringAndClear();
903 		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
904 
905 		// write line
906 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
907 		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_LINE, bCreateNewline, sal_True);
908 
909 		ImpExportDescription( xShape ); // #i68101#
910 		ImpExportEvents( xShape );
911 		ImpExportGluePoints( xShape );
912 		ImpExportText( xShape );
913 	}
914 }
915 
916 //////////////////////////////////////////////////////////////////////////////
917 
918 void XMLShapeExport::ImpExportEllipseShape(
919 	const uno::Reference< drawing::XShape >& xShape,
920 	XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
921 {
922 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
923 	if(xPropSet.is())
924 	{
925 		// get size to decide between Circle and Ellipse
926 		awt::Size aSize = xShape->getSize();
927 		sal_Int32 nRx((aSize.Width + 1) / 2);
928 		sal_Int32 nRy((aSize.Height + 1) / 2);
929 		sal_Bool bCircle(nRx == nRy);
930 
931 		// Transformation
932 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
933 
934 		drawing::CircleKind eKind = drawing::CircleKind_FULL;
935 		xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleKind")) ) >>= eKind;
936 		if( eKind != drawing::CircleKind_FULL )
937 		{
938 			OUStringBuffer sStringBuffer;
939 			sal_Int32 nStartAngle = 0;
940 			sal_Int32 nEndAngle = 0;
941 			xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleStartAngle")) ) >>= nStartAngle;
942 			xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("CircleEndAngle")) ) >>= nEndAngle;
943 
944 			const double dStartAngle = nStartAngle / 100.0;
945 			const double dEndAngle = nEndAngle / 100.0;
946 
947 			// export circle kind
948 			SvXMLUnitConverter::convertEnum( sStringBuffer, (sal_uInt16)eKind, aXML_CircleKind_EnumMap );
949 			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_KIND, sStringBuffer.makeStringAndClear() );
950 
951 			// export start angle
952 			SvXMLUnitConverter::convertDouble( sStringBuffer, dStartAngle );
953 			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_ANGLE, sStringBuffer.makeStringAndClear() );
954 
955 			// export end angle
956 			SvXMLUnitConverter::convertDouble( sStringBuffer, dEndAngle );
957 			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_ANGLE, sStringBuffer.makeStringAndClear() );
958 		}
959 
960 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
961 
962 		if(bCircle)
963 		{
964 			// write circle
965 			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CIRCLE, bCreateNewline, sal_True);
966 
967 			ImpExportDescription( xShape ); // #i68101#
968 			ImpExportEvents( xShape );
969 			ImpExportGluePoints( xShape );
970 			ImpExportText( xShape );
971 		}
972 		else
973 		{
974 			// write ellipse
975 			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_ELLIPSE, bCreateNewline, sal_True);
976 
977 			ImpExportDescription( xShape ); // #i68101#
978 			ImpExportEvents( xShape );
979 			ImpExportGluePoints( xShape );
980 			ImpExportText( xShape );
981 		}
982 	}
983 }
984 
985 //////////////////////////////////////////////////////////////////////////////
986 
987 void XMLShapeExport::ImpExportPolygonShape(
988 	const uno::Reference< drawing::XShape >& xShape,
989 	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
990 {
991 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
992 	if(xPropSet.is())
993 	{
994 		sal_Bool bClosed(eShapeType == XmlShapeTypeDrawPolyPolygonShape
995 			|| eShapeType == XmlShapeTypeDrawClosedBezierShape);
996 		sal_Bool bBezier(eShapeType == XmlShapeTypeDrawClosedBezierShape
997 			|| eShapeType == XmlShapeTypeDrawOpenBezierShape);
998 
999 		// get matrix
1000 		::basegfx::B2DHomMatrix aMatrix;
1001 		ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
1002 
1003 		// decompose and correct abour pRefPoint
1004 		::basegfx::B2DTuple aTRScale;
1005 		double fTRShear(0.0);
1006 		double fTRRotate(0.0);
1007 		::basegfx::B2DTuple aTRTranslate;
1008 		ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
1009 
1010 		// use features and write
1011 		ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
1012 
1013 		// create and export ViewBox
1014 		awt::Point aPoint(0, 0);
1015 		awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
1016 		SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
1017 		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
1018 
1019 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1020 
1021 		if(bBezier)
1022 		{
1023 			// get PolygonBezier
1024 			uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) );
1025             drawing::PolyPolygonBezierCoords* pSourcePolyPolygon =
1026 				(drawing::PolyPolygonBezierCoords*)aAny.getValue();
1027 
1028 			if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
1029 			{
1030 				sal_Int32 nOuterCnt(pSourcePolyPolygon->Coordinates.getLength());
1031 				drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray();
1032 				drawing::FlagSequence*  pOuterFlags = pSourcePolyPolygon->Flags.getArray();
1033 
1034 				if(pOuterSequence && pOuterFlags)
1035 				{
1036 					// prepare svx:d element export
1037 					SdXMLImExSvgDElement aSvgDElement(aViewBox);
1038 
1039 					for(sal_Int32 a(0L); a < nOuterCnt; a++)
1040 					{
1041 						drawing::PointSequence* pSequence = pOuterSequence++;
1042 						drawing::FlagSequence* pFlags = pOuterFlags++;
1043 
1044 						if(pSequence && pFlags)
1045 						{
1046 							aSvgDElement.AddPolygon(pSequence, pFlags,
1047 								aPoint, aSize, bClosed);
1048 						}
1049 					}
1050 
1051 					// write point array
1052 					mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString());
1053 				}
1054 
1055 				// write object now
1056 				SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PATH, bCreateNewline, sal_True);
1057 
1058 				ImpExportDescription( xShape ); // #i68101#
1059 				ImpExportEvents( xShape );
1060 				ImpExportGluePoints( xShape );
1061 				ImpExportText( xShape );
1062 			}
1063 		}
1064 		else
1065 		{
1066 			// get non-bezier polygon
1067 			uno::Any aAny( xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Geometry"))) );
1068 			drawing::PointSequenceSequence* pSourcePolyPolygon = (drawing::PointSequenceSequence*)aAny.getValue();
1069 
1070 			if(pSourcePolyPolygon && pSourcePolyPolygon->getLength())
1071 			{
1072 				sal_Int32 nOuterCnt(pSourcePolyPolygon->getLength());
1073 
1074 				if(1L == nOuterCnt && !bBezier)
1075 				{
1076 					// simple polygon shape, can be written as svg:points sequence
1077 					drawing::PointSequence* pSequence = pSourcePolyPolygon->getArray();
1078 					if(pSequence)
1079 					{
1080 						SdXMLImExPointsElement aPoints(pSequence, aViewBox, aPoint, aSize,
1081 							// #96328#
1082 							bClosed);
1083 
1084 						// write point array
1085 						mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPoints.GetExportString());
1086 					}
1087 
1088 					// write object now
1089 					SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW,
1090 						bClosed ? XML_POLYGON : XML_POLYLINE , bCreateNewline, sal_True);
1091 
1092 					ImpExportDescription( xShape ); // #i68101#
1093 					ImpExportEvents( xShape );
1094 					ImpExportGluePoints( xShape );
1095 					ImpExportText( xShape );
1096 				}
1097 				else
1098 				{
1099 					// polypolygon or bezier, needs to be written as a svg:path sequence
1100 					drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray();
1101 					if(pOuterSequence)
1102 					{
1103 						// prepare svx:d element export
1104 						SdXMLImExSvgDElement aSvgDElement(aViewBox);
1105 
1106 						for(sal_Int32 a(0L); a < nOuterCnt; a++)
1107 						{
1108 							drawing::PointSequence* pSequence = pOuterSequence++;
1109 							if(pSequence)
1110 							{
1111 								aSvgDElement.AddPolygon(pSequence, 0L, aPoint,
1112 									aSize, bClosed);
1113 							}
1114 						}
1115 
1116 						// write point array
1117 						mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString());
1118 					}
1119 
1120 					// write object now
1121 					SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PATH, bCreateNewline, sal_True);
1122 
1123 					ImpExportDescription( xShape ); // #i68101#
1124 					ImpExportEvents( xShape );
1125 					ImpExportGluePoints( xShape );
1126 					ImpExportText( xShape );
1127 				}
1128 			}
1129 		}
1130 	}
1131 }
1132 
1133 //////////////////////////////////////////////////////////////////////////////
1134 
1135 void XMLShapeExport::ImpExportGraphicObjectShape(
1136 	const uno::Reference< drawing::XShape >& xShape,
1137 	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
1138 {
1139 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1140 	if(xPropSet.is())
1141 	{
1142 		sal_Bool bIsEmptyPresObj = sal_False;
1143 		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1144 
1145 		// Transformation
1146 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1147 
1148 		OUString sImageURL;
1149 
1150 		if(eShapeType == XmlShapeTypePresGraphicObjectShape)
1151 			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_GRAPHIC) );
1152 
1153 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1154 		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
1155 								  XML_FRAME, bCreateNewline, sal_True );
1156 
1157 		const bool bSaveBackwardsCompatible = ( mrExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE );
1158 
1159 		if( !bIsEmptyPresObj || bSaveBackwardsCompatible )
1160 		{
1161 			if( !bIsEmptyPresObj )
1162 			{
1163 				OUString aStreamURL;
1164 				OUString aStr;
1165 
1166 				xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL"))) >>= aStreamURL;
1167 				xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL"))) >>= sImageURL;
1168 
1169 				OUString aResolveURL( sImageURL );
1170 				const rtl::OUString sPackageURL( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.Package:") );
1171 
1172 					// sj: trying to preserve the filename
1173 				if ( aStreamURL.match( sPackageURL, 0 ) )
1174 				{
1175 					rtl::OUString sRequestedName( aStreamURL.copy( sPackageURL.getLength(), aStreamURL.getLength() - sPackageURL.getLength() ) );
1176 					sal_Int32 nLastIndex = sRequestedName.lastIndexOf( '/' ) + 1;
1177 					if ( ( nLastIndex > 0 ) && ( nLastIndex < sRequestedName.getLength() ) )
1178 						sRequestedName = sRequestedName.copy( nLastIndex, sRequestedName.getLength() - nLastIndex );
1179 					nLastIndex = sRequestedName.lastIndexOf( '.' );
1180 					if ( nLastIndex >= 0 )
1181 						sRequestedName = sRequestedName.copy( 0, nLastIndex );
1182 					if ( sRequestedName.getLength() )
1183 					{
1184 						aResolveURL = aResolveURL.concat( OUString(RTL_CONSTASCII_USTRINGPARAM("?requestedName=")));
1185 						aResolveURL = aResolveURL.concat( sRequestedName );
1186 					}
1187 				}
1188 
1189 				aStr = mrExport.AddEmbeddedGraphicObject( aResolveURL );
1190 				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr );
1191 
1192 				if( aStr.getLength() )
1193 				{
1194 					if( aStr[ 0 ] == '#' )
1195 					{
1196 						aStreamURL = OUString::createFromAscii( "vnd.sun.star.Package:" );
1197 						aStreamURL = aStreamURL.concat( aStr.copy( 1, aStr.getLength() - 1 ) );
1198 					}
1199 
1200 					// update stream URL for load on demand
1201 					uno::Any aAny;
1202 					aAny <<= aStreamURL;
1203 					xPropSet->setPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicStreamURL")), aAny );
1204 
1205 					mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1206 					mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1207 					mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1208 				}
1209 			}
1210 			else
1211 			{
1212 				OUString aStr;
1213 				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr );
1214 				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1215 				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1216 				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1217 			}
1218 
1219 			{
1220 				SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, sal_True, sal_True);
1221 
1222 				if( sImageURL.getLength() )
1223 				{
1224 					// optional office:binary-data
1225 					mrExport.AddEmbeddedGraphicObjectAsBase64( sImageURL );
1226 				}
1227 				if( !bIsEmptyPresObj )
1228 					ImpExportText( xShape );
1229 			}
1230 		}
1231 
1232 		ImpExportEvents( xShape );
1233 		ImpExportGluePoints( xShape );
1234 
1235 		// image map
1236 		GetExport().GetImageMapExport().Export( xPropSet );
1237 		ImpExportDescription( xShape ); // #i68101#
1238 	}
1239 }
1240 
1241 //////////////////////////////////////////////////////////////////////////////
1242 
1243 void XMLShapeExport::ImpExportChartShape(
1244 	const uno::Reference< drawing::XShape >& xShape,
1245 	XmlShapeType eShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint,
1246     SvXMLAttributeList* pAttrList )
1247 {
1248 	ImpExportOLE2Shape( xShape, eShapeType, nFeatures, pRefPoint, pAttrList );
1249 }
1250 
1251 //////////////////////////////////////////////////////////////////////////////
1252 
1253 void XMLShapeExport::ImpExportControlShape(
1254 	const uno::Reference< drawing::XShape >& xShape,
1255 	XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
1256 {
1257 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1258 	if(xPropSet.is())
1259 	{
1260 		// Transformation
1261 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1262 	}
1263 
1264 	uno::Reference< drawing::XControlShape > xControl( xShape, uno::UNO_QUERY );
1265 	DBG_ASSERT( xControl.is(), "Control shape is not supporting XControlShape" );
1266 	if( xControl.is() )
1267 	{
1268 		uno::Reference< beans::XPropertySet > xControlModel( xControl->getControl(), uno::UNO_QUERY );
1269 		DBG_ASSERT( xControlModel.is(), "Control shape has not XControlModel" );
1270 		if( xControlModel.is() )
1271 		{
1272 			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONTROL, mrExport.GetFormExport()->getControlId( xControlModel ) );
1273 		}
1274 	}
1275 
1276 	sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1277 	SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONTROL, bCreateNewline, sal_True);
1278 
1279 	ImpExportDescription( xShape ); // #i68101#
1280 }
1281 
1282 //////////////////////////////////////////////////////////////////////////////
1283 
1284 void XMLShapeExport::ImpExportConnectorShape(
1285 	const uno::Reference< drawing::XShape >& xShape,
1286 	XmlShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
1287 {
1288 	uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
1289 
1290 	OUString aStr;
1291 	OUStringBuffer sStringBuffer;
1292 
1293 	// export connection kind
1294 	drawing::ConnectorType eType = drawing::ConnectorType_STANDARD;
1295 	uno::Any aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeKind")));
1296 	aAny >>= eType;
1297 
1298 	if( eType != drawing::ConnectorType_STANDARD )
1299 	{
1300 		SvXMLUnitConverter::convertEnum( sStringBuffer, (sal_uInt16)eType, aXML_ConnectionKind_EnumMap );
1301 		aStr = sStringBuffer.makeStringAndClear();
1302 		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TYPE, aStr);
1303 	}
1304 
1305 	// export line skew
1306 	sal_Int32 nDelta1 = 0, nDelta2 = 0, nDelta3 = 0;
1307 
1308 	aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine1Delta")));
1309 	aAny >>= nDelta1;
1310 	aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine2Delta")));
1311 	aAny >>= nDelta2;
1312 	aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EdgeLine3Delta")));
1313 	aAny >>= nDelta3;
1314 
1315 	if( nDelta1 != 0 || nDelta2 != 0 || nDelta3 != 0 )
1316 	{
1317 		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDelta1);
1318 		if( nDelta2 != 0 || nDelta3 != 0 )
1319 		{
1320 			const char aSpace = ' ';
1321 			sStringBuffer.appendAscii( &aSpace, 1 );
1322 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDelta2);
1323 			if( nDelta3 != 0 )
1324 			{
1325 				sStringBuffer.appendAscii( &aSpace, 1 );
1326 				mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDelta3);
1327 			}
1328 		}
1329 
1330 		aStr = sStringBuffer.makeStringAndClear();
1331 		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LINE_SKEW, aStr);
1332 	}
1333 
1334 	// export start and end point
1335 	awt::Point aStart(0,0);
1336 	awt::Point aEnd(1,1);
1337 
1338     // --> OD 2004-08-09 #i36248# - Get <StartPositionInHoriL2R> and
1339     // <EndPositionInHoriL2R>, if they exist and if the document is exported
1340     // into the OpenOffice.org file format.
1341     // These properties only exist at service com::sun::star::text::Shape - the
1342     // Writer UNO service for shapes.
1343     // This code is needed, because the positioning attributes in the
1344     // OpenOffice.org file format are given in horizontal left-to-right layout
1345     // regardless the layout direction the shape is in. In the OASIS Open Office
1346     // file format the positioning attributes are correctly given in the layout
1347     // direction the shape is in. Thus, this code provides the conversion from
1348     // the OASIS Open Office file format to the OpenOffice.org file format.
1349     if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 &&
1350          xProps->getPropertySetInfo()->hasPropertyByName(
1351             OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) &&
1352          xProps->getPropertySetInfo()->hasPropertyByName(
1353             OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) )
1354     {
1355         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) >>= aStart;
1356         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) >>= aEnd;
1357     }
1358     else
1359     {
1360         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition"))) >>= aStart;
1361         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition"))) >>= aEnd;
1362     }
1363     // <--
1364 
1365 	if( pRefPoint )
1366 	{
1367 		aStart.X -= pRefPoint->X;
1368 		aStart.Y -= pRefPoint->Y;
1369 		aEnd.X -= pRefPoint->X;
1370 		aEnd.Y -= pRefPoint->Y;
1371 	}
1372 
1373 	if( nFeatures & SEF_EXPORT_X )
1374 	{
1375 		// svg: x1
1376 		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.X);
1377 		aStr = sStringBuffer.makeStringAndClear();
1378 		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
1379 	}
1380 	else
1381 	{
1382 		aEnd.X -= aStart.X;
1383 	}
1384 
1385 	if( nFeatures & SEF_EXPORT_Y )
1386 	{
1387 		// svg: y1
1388 		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.Y);
1389 		aStr = sStringBuffer.makeStringAndClear();
1390 		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
1391 	}
1392 	else
1393 	{
1394 		aEnd.Y -= aStart.Y;
1395 	}
1396 
1397 	// svg: x2
1398 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.X);
1399 	aStr = sStringBuffer.makeStringAndClear();
1400 	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
1401 
1402 	// svg: y2
1403 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.Y);
1404 	aStr = sStringBuffer.makeStringAndClear();
1405 	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
1406 
1407 	// #i39320#
1408 	uno::Reference< uno::XInterface > xRefS;
1409 	uno::Reference< uno::XInterface > xRefE;
1410 
1411 	// export start connection
1412 	xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartShape") ) ) >>= xRefS;
1413 	if( xRefS.is() )
1414 	{
1415 		const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefS );
1416 		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_SHAPE, rShapeId);
1417 
1418 		aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartGluePointIndex")) );
1419 		sal_Int32 nGluePointId = 0;
1420 		if( aAny >>= nGluePointId )
1421 		{
1422 			if( nGluePointId != -1 )
1423 			{
1424 				mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_GLUE_POINT, OUString::valueOf( nGluePointId ));
1425 			}
1426 		}
1427 	}
1428 
1429 	// export end connection
1430 	xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndShape")) ) >>= xRefE;
1431 	if( xRefE.is() )
1432 	{
1433 		const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefE );
1434 		mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_SHAPE, rShapeId);
1435 
1436 		aAny = xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndGluePointIndex")) );
1437 		sal_Int32 nGluePointId = 0;
1438 		if( aAny >>= nGluePointId )
1439 		{
1440 			if( nGluePointId != -1 )
1441 			{
1442 				mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_GLUE_POINT, OUString::valueOf( nGluePointId ));
1443 			}
1444 		}
1445 	}
1446 
1447 	if( xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("PolyPolygonBezier") ) ) >>= aAny )
1448 	{
1449 		// get PolygonBezier
1450 		drawing::PolyPolygonBezierCoords* pSourcePolyPolygon =
1451 			(drawing::PolyPolygonBezierCoords*)aAny.getValue();
1452 
1453 		if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
1454 		{
1455 			sal_Int32 nOuterCnt(pSourcePolyPolygon->Coordinates.getLength());
1456 			drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray();
1457 			drawing::FlagSequence*  pOuterFlags = pSourcePolyPolygon->Flags.getArray();
1458 
1459 			if(pOuterSequence && pOuterFlags)
1460 			{
1461 				// prepare svx:d element export
1462 				awt::Point aPoint( 0, 0 );
1463 				awt::Size aSize( 1, 1 );
1464 				SdXMLImExViewBox aViewBox( 0, 0, 1, 1 );
1465 				SdXMLImExSvgDElement aSvgDElement(aViewBox);
1466 
1467 				for(sal_Int32 a(0L); a < nOuterCnt; a++)
1468 				{
1469 					drawing::PointSequence* pSequence = pOuterSequence++;
1470 					drawing::FlagSequence* pFlags = pOuterFlags++;
1471 
1472 					if(pSequence && pFlags)
1473 					{
1474 						aSvgDElement.AddPolygon(pSequence, pFlags,
1475 							aPoint, aSize, sal_False );
1476 					}
1477 				}
1478 
1479 				// write point array
1480 				mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString());
1481 			}
1482 		}
1483 	}
1484 
1485 	// write connector shape. Add Export later.
1486 	sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1487 	SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONNECTOR, bCreateNewline, sal_True);
1488 
1489 	ImpExportDescription( xShape ); // #i68101#
1490 	ImpExportEvents( xShape );
1491 	ImpExportGluePoints( xShape );
1492 	ImpExportText( xShape );
1493 }
1494 
1495 //////////////////////////////////////////////////////////////////////////////
1496 
1497 void XMLShapeExport::ImpExportMeasureShape(
1498 	const uno::Reference< drawing::XShape >& xShape,
1499 	XmlShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
1500 {
1501 	uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
1502 
1503 	OUString aStr;
1504 	OUStringBuffer sStringBuffer;
1505 
1506 	// export start and end point
1507 	awt::Point aStart(0,0);
1508 	awt::Point aEnd(1,1);
1509 
1510     // --> OD 2004-08-09 #i36248# - Get <StartPositionInHoriL2R> and
1511     // <EndPositionInHoriL2R>, if they exist and if the document is exported
1512     // into the OpenOffice.org file format.
1513     // These properties only exist at service com::sun::star::text::Shape - the
1514     // Writer UNO service for shapes.
1515     // This code is needed, because the positioning attributes in the
1516     // OpenOffice.org file format are given in horizontal left-to-right layout
1517     // regardless the layout direction the shape is in. In the OASIS Open Office
1518     // file format the positioning attributes are correctly given in the layout
1519     // direction the shape is in. Thus, this code provides the conversion from
1520     // the OASIS Open Office file format to the OpenOffice.org file format.
1521     if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 &&
1522          xProps->getPropertySetInfo()->hasPropertyByName(
1523             OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) &&
1524          xProps->getPropertySetInfo()->hasPropertyByName(
1525             OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) )
1526     {
1527         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPositionInHoriL2R"))) >>= aStart;
1528         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPositionInHoriL2R"))) >>= aEnd;
1529     }
1530     else
1531     {
1532         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("StartPosition"))) >>= aStart;
1533         xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("EndPosition"))) >>= aEnd;
1534     }
1535     // <--
1536 
1537 	if( pRefPoint )
1538 	{
1539 		aStart.X -= pRefPoint->X;
1540 		aStart.Y -= pRefPoint->Y;
1541 		aEnd.X -= pRefPoint->X;
1542 		aEnd.Y -= pRefPoint->Y;
1543 	}
1544 
1545 	if( nFeatures & SEF_EXPORT_X )
1546 	{
1547 		// svg: x1
1548 		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.X);
1549 		aStr = sStringBuffer.makeStringAndClear();
1550 		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
1551 	}
1552 	else
1553 	{
1554 		aEnd.X -= aStart.X;
1555 	}
1556 
1557 	if( nFeatures & SEF_EXPORT_Y )
1558 	{
1559 		// svg: y1
1560 		mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aStart.Y);
1561 		aStr = sStringBuffer.makeStringAndClear();
1562 		mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
1563 	}
1564 	else
1565 	{
1566 		aEnd.Y -= aStart.Y;
1567 	}
1568 
1569 	// svg: x2
1570 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.X);
1571 	aStr = sStringBuffer.makeStringAndClear();
1572 	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
1573 
1574 	// svg: y2
1575 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, aEnd.Y);
1576 	aStr = sStringBuffer.makeStringAndClear();
1577 	mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
1578 
1579 	// write measure shape
1580 	sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1581 	SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_MEASURE, bCreateNewline, sal_True);
1582 
1583 	ImpExportDescription( xShape ); // #i68101#
1584 	ImpExportEvents( xShape );
1585 	ImpExportGluePoints( xShape );
1586 
1587 	uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
1588 	if( xText.is() )
1589 		mrExport.GetTextParagraphExport()->exportText( xText );
1590 }
1591 
1592 //////////////////////////////////////////////////////////////////////////////
1593 
1594 void XMLShapeExport::ImpExportOLE2Shape(
1595 	const uno::Reference< drawing::XShape >& xShape,
1596 	XmlShapeType eShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */,
1597     SvXMLAttributeList* pAttrList /* = NULL */ )
1598 {
1599 	uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1600 	uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
1601 
1602 	DBG_ASSERT( xPropSet.is() && xNamed.is(), "ole shape is not implementing needed interfaces");
1603 	if(xPropSet.is() && xNamed.is())
1604 	{
1605 		// Transformation
1606 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1607 
1608 		sal_Bool bIsEmptyPresObj = sal_False;
1609 
1610 		// presentation settings
1611 		if(eShapeType == XmlShapeTypePresOLE2Shape)
1612 			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_OBJECT) );
1613 		else if(eShapeType == XmlShapeTypePresChartShape)
1614 			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_CHART) );
1615 		else if(eShapeType == XmlShapeTypePresSheetShape)
1616 			bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_TABLE) );
1617 
1618 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1619 		sal_Bool bExportEmbedded(0 != (mrExport.getExportFlags() & EXPORT_EMBEDDED));
1620 		OUString sPersistName;
1621 		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
1622 								  XML_FRAME, bCreateNewline, sal_True );
1623 
1624 		const bool bSaveBackwardsCompatible = ( mrExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE );
1625 
1626 		if( !bIsEmptyPresObj || bSaveBackwardsCompatible )
1627 		{
1628             if (pAttrList)
1629             {
1630                 mrExport.AddAttributeList(pAttrList);
1631             }
1632 
1633 			OUString sClassId;
1634 			OUString sURL;
1635 			sal_Bool bInternal = false;
1636 			xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("IsInternal"))) >>= bInternal;
1637 
1638 			if( !bIsEmptyPresObj )
1639 			{
1640 
1641 				if ( bInternal )
1642 				{
1643 					// OOo internal links have no storage persistance, URL is stored in the XML file
1644 					// the result LinkURL is empty in case the object is not a link
1645 					xPropSet->getPropertyValue( OUString::createFromAscii( "LinkURL" ) ) >>= sURL;
1646 				}
1647 
1648 				xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM( "PersistName" ) ) ) >>= sPersistName;
1649 				if ( !sURL.getLength() )
1650 				{
1651 					if( sPersistName.getLength() )
1652 					{
1653 						sURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.EmbeddedObject:" ) );
1654 						sURL += sPersistName;
1655 					}
1656 				}
1657 
1658 				if( !bInternal )
1659 					xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID"))) >>= sClassId;
1660 
1661 				if( sClassId.getLength() )
1662 					mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CLASS_ID, sClassId );
1663 				if(!bExportEmbedded)
1664 				{
1665 					// xlink:href
1666 					if( sURL.getLength() )
1667 					{
1668 						// #96717# in theorie, if we don't have a url we shouldn't even
1669 						// export this ole shape. But practical its to risky right now
1670 						// to change this so we better dispose this on load
1671 						sURL = mrExport.AddEmbeddedObject( sURL );
1672 
1673 						mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL );
1674 						mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1675 						mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1676 						mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1677 					}
1678 				}
1679 			}
1680 			else
1681 			{
1682 				// export empty href for empty placeholders to be valid odf
1683 				OUString sEmptyURL;
1684 
1685 				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sEmptyURL );
1686 				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1687 				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1688 				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1689 			}
1690 
1691 			enum XMLTokenEnum eElem = sClassId.getLength() ? XML_OBJECT_OLE : XML_OBJECT;
1692 			SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, eElem, sal_True, sal_True );
1693 
1694 			if(bExportEmbedded && !bIsEmptyPresObj)
1695 			{
1696 				// #100592#
1697 				if(bInternal)
1698 				{
1699 					// embedded XML
1700 					uno::Reference< lang::XComponent > xComp;
1701 					xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) ) >>= xComp;
1702 					DBG_ASSERT( xComp.is(), "no xModel for own OLE format" );
1703 					mrExport.ExportEmbeddedOwnObject( xComp );
1704 				}
1705 				else
1706 				{
1707 					// embed as Base64
1708 					// this is an alien object ( currently MSOLE is the only supported type of such objects )
1709 					// in case it is not an OASIS format the object should be asked to store replacement image if possible
1710 
1711 					::rtl::OUString sURLRequest( sURL );
1712     				if ( ( mrExport.getExportFlags() & EXPORT_OASIS ) == 0 )
1713 						sURLRequest += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "?oasis=false" ) );
1714 					mrExport.AddEmbeddedObjectAsBase64( sURLRequest );
1715 				}
1716 			}
1717 		}
1718 		if( !bIsEmptyPresObj )
1719 		{
1720 			OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
1721 			sURL += sPersistName;
1722 			if( !bExportEmbedded )
1723 			{
1724 				sURL = GetExport().AddEmbeddedObject( sURL );
1725 				mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL );
1726 				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1727 				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1728 				mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1729 			}
1730 
1731 			SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW,
1732 									  XML_IMAGE, sal_False, sal_True );
1733 
1734 			if( bExportEmbedded )
1735 				GetExport().AddEmbeddedObjectAsBase64( sURL );
1736 		}
1737 
1738 		ImpExportEvents( xShape );
1739 		ImpExportGluePoints( xShape );
1740 		ImpExportDescription( xShape ); // #i68101#
1741 	}
1742 }
1743 
1744 //////////////////////////////////////////////////////////////////////////////
1745 
1746 void XMLShapeExport::ImpExportPageShape(
1747 	const uno::Reference< drawing::XShape >& xShape,
1748 	XmlShapeType eShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
1749 {
1750 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1751 	if(xPropSet.is())
1752 	{
1753 		// #86163# Transformation
1754 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1755 
1756 		// export page number used for this page
1757 		uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1758 		const OUString aPageNumberStr(RTL_CONSTASCII_USTRINGPARAM("PageNumber"));
1759 		if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
1760 		{
1761 			sal_Int32 nPageNumber = 0;
1762 			xPropSet->getPropertyValue(aPageNumberStr) >>= nPageNumber;
1763 			if( nPageNumber )
1764 				mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_PAGE_NUMBER, OUString::valueOf(nPageNumber));
1765 		}
1766 
1767 		// a presentation page shape, normally used on notes pages only. If
1768 		// it is used not as presentation shape, it may have been created with
1769 		// copy-paste exchange between draw and impress (this IS possible...)
1770 		if(eShapeType == XmlShapeTypePresPageShape)
1771 		{
1772 			mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS,
1773                                  XML_PRESENTATION_PAGE);
1774 		}
1775 
1776 		// write Page shape
1777 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1778 		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, bCreateNewline, sal_True);
1779 	}
1780 }
1781 
1782 //////////////////////////////////////////////////////////////////////////////
1783 
1784 void XMLShapeExport::ImpExportCaptionShape(
1785 	const uno::Reference< drawing::XShape >& xShape,
1786 	XmlShapeType, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
1787 {
1788 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1789 	if(xPropSet.is())
1790 	{
1791 		// Transformation
1792 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1793 
1794 		// evtl. corner radius?
1795 		sal_Int32 nCornerRadius(0L);
1796 		xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CornerRadius"))) >>= nCornerRadius;
1797 		if(nCornerRadius)
1798 		{
1799 			OUStringBuffer sStringBuffer;
1800 			mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nCornerRadius);
1801 			mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
1802 		}
1803 
1804 		awt::Point aCaptionPoint;
1805 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CaptionPoint" ) ) ) >>= aCaptionPoint;
1806 
1807 		mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aCaptionPoint.X);
1808 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_X, msBuffer.makeStringAndClear() );
1809 		mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aCaptionPoint.Y);
1810 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_Y, msBuffer.makeStringAndClear() );
1811 
1812 		// write Caption shape. Add export later.
1813 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1814 		sal_Bool bAnnotation( (nFeatures & SEF_EXPORT_ANNOTATION) == SEF_EXPORT_ANNOTATION );
1815 
1816         SvXMLElementExport aObj( mrExport,
1817 								 (bAnnotation ? XML_NAMESPACE_OFFICE
1818 								 			  : XML_NAMESPACE_DRAW),
1819 								 (bAnnotation ?	XML_ANNOTATION : XML_CAPTION),
1820 								 bCreateNewline, sal_True );
1821 
1822 		ImpExportDescription( xShape ); // #i68101#
1823 		ImpExportEvents( xShape );
1824 		ImpExportGluePoints( xShape );
1825 		if( bAnnotation )
1826 			mrExport.exportAnnotationMeta( xShape );
1827 		ImpExportText( xShape );
1828 	}
1829 }
1830 
1831 //////////////////////////////////////////////////////////////////////////////
1832 
1833 void XMLShapeExport::ImpExportFrameShape(
1834 	const uno::Reference< drawing::XShape >& xShape,
1835 	XmlShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint)
1836 {
1837 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1838 	if(xPropSet.is())
1839 	{
1840 		// Transformation
1841 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1842 
1843 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1844 		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
1845 								  XML_FRAME, bCreateNewline, sal_True );
1846 
1847 		// export frame url
1848 		OUString aStr;
1849 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "FrameURL" ) ) ) >>= aStr;
1850         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
1851         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1852         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1853         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1854 
1855 		// export name
1856 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "FrameName" ) ) ) >>= aStr;
1857 		if( aStr.getLength() )
1858 			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FRAME_NAME, aStr );
1859 
1860 		// write floating frame
1861 		{
1862 			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_FLOATING_FRAME, sal_True, sal_True);
1863 		}
1864 	}
1865 }
1866 
1867 //////////////////////////////////////////////////////////////////////////////
1868 
1869 void XMLShapeExport::ImpExportAppletShape(
1870 	const uno::Reference< drawing::XShape >& xShape,
1871 	XmlShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint)
1872 {
1873 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1874 	if(xPropSet.is())
1875 	{
1876 		// Transformation
1877 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1878 
1879 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1880 		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
1881 								  XML_FRAME, bCreateNewline, sal_True );
1882 
1883 		// export frame url
1884 		OUString aStr;
1885 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCodeBase" ) ) ) >>= aStr;
1886         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
1887         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1888         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1889         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1890 
1891 		// export draw:applet-name
1892 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletName" ) ) ) >>= aStr;
1893 		if( aStr.getLength() )
1894 			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_APPLET_NAME, aStr );
1895 
1896 		// export draw:code
1897 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCode" ) ) ) >>= aStr;
1898 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CODE, aStr );
1899 
1900 		// export draw:may-script
1901 		sal_Bool bIsScript = false;
1902 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletIsScript" ) ) ) >>= bIsScript;
1903 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MAY_SCRIPT, bIsScript ? XML_TRUE : XML_FALSE );
1904 
1905 		{
1906 			// write applet
1907 			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_APPLET, sal_True, sal_True);
1908 
1909 			// export parameters
1910 			uno::Sequence< beans::PropertyValue > aCommands;
1911 			xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "AppletCommands" ) ) ) >>= aCommands;
1912 			const sal_Int32 nCount = aCommands.getLength();
1913 			for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
1914 			{
1915 				aCommands[nIndex].Value >>= aStr;
1916 				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aCommands[nIndex].Name );
1917 				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
1918 				SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True );
1919 			}
1920 		}
1921 	}
1922 }
1923 
1924 //////////////////////////////////////////////////////////////////////////////
1925 
1926 void XMLShapeExport::ImpExportPluginShape(
1927 	const uno::Reference< drawing::XShape >& xShape,
1928 	XmlShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint)
1929 {
1930 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1931 	if(xPropSet.is())
1932 	{
1933 		// Transformation
1934 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1935 
1936 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1937 		SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
1938 								  XML_FRAME, bCreateNewline, sal_True );
1939 
1940 		// export plugin url
1941 		OUString aStr;
1942 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginURL" ) ) ) >>= aStr;
1943         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
1944         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1945         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1946         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1947 
1948 
1949 		// export mime-type
1950 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginMimeType" ) ) ) >>= aStr;
1951 		if(aStr.getLength())
1952 			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, aStr );
1953 
1954 		{
1955 			// write plugin
1956 			SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, sal_True, sal_True);
1957 
1958 			// export parameters
1959 			uno::Sequence< beans::PropertyValue > aCommands;
1960 			xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginCommands" ) ) ) >>= aCommands;
1961 			const sal_Int32 nCount = aCommands.getLength();
1962 			for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
1963 			{
1964 				aCommands[nIndex].Value >>= aStr;
1965 				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aCommands[nIndex].Name );
1966 				mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
1967 				SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True );
1968 			}
1969 		}
1970 	}
1971 }
1972 
1973 //////////////////////////////////////////////////////////////////////////////
1974 
1975 void XMLShapeExport::ImpExportMediaShape(
1976 	const uno::Reference< drawing::XShape >& xShape,
1977 	XmlShapeType eShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint)
1978 {
1979 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1980 	if(xPropSet.is())
1981 	{
1982 		// Transformation
1983 		ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1984 
1985 		if(eShapeType == XmlShapeTypePresMediaShape)
1986 			ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_OBJECT) );
1987 
1988 		sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
1989 		SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
1990 								  XML_FRAME, bCreateNewline, sal_True );
1991 
1992 		// export media url
1993 		OUString aMediaURL;
1994 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ) ) >>= aMediaURL;
1995         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference( aMediaURL ) );
1996         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1997         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1998         mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
1999 
2000 		// export mime-type
2001 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.media" ) ) );
2002 
2003 		// write plugin
2004 		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & SEF_EXPORT_NO_WS ), sal_True);
2005 
2006 		// export parameters
2007 		const OUString aFalseStr( RTL_CONSTASCII_USTRINGPARAM( "false" ) ), aTrueStr( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
2008 
2009 		sal_Bool bLoop = false;
2010 		const OUString aLoopStr( RTL_CONSTASCII_USTRINGPARAM( "Loop" ) );
2011 		xPropSet->getPropertyValue( aLoopStr ) >>= bLoop;
2012 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aLoopStr );
2013 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bLoop ? aTrueStr : aFalseStr );
2014 		delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );
2015 
2016 		sal_Bool bMute = false;
2017 		const OUString aMuteStr( RTL_CONSTASCII_USTRINGPARAM( "Mute" ) );
2018 		xPropSet->getPropertyValue( aMuteStr ) >>= bMute;
2019 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aMuteStr );
2020 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bMute ? aTrueStr : aFalseStr );
2021 		delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );
2022 
2023 		sal_Int16 nVolumeDB = 0;
2024 		const OUString aVolumeDBStr( RTL_CONSTASCII_USTRINGPARAM( "VolumeDB" ) );
2025 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "VolumeDB" ) ) ) >>= nVolumeDB;
2026 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aVolumeDBStr );
2027 		mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, OUString::valueOf( static_cast< sal_Int32 >( nVolumeDB ) ) );
2028 		delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );
2029 
2030 		media::ZoomLevel eZoom;
2031 		const OUString aZoomStr( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) );
2032 		OUString aZoomValue;
2033 		xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) ) ) >>= eZoom;
2034 		switch( eZoom )
2035 		{
2036 			case( media::ZoomLevel_ZOOM_1_TO_4 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "25%" ) ); break;
2037 			case( media::ZoomLevel_ZOOM_1_TO_2 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "50%" ) ); break;
2038 			case( media::ZoomLevel_ORIGINAL ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "100%" ) ); break;
2039 			case( media::ZoomLevel_ZOOM_2_TO_1 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "200%" ) ); break;
2040 			case( media::ZoomLevel_ZOOM_4_TO_1 ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "400%" ) ); break;
2041 		    case( media::ZoomLevel_FIT_TO_WINDOW ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "fit" ) ); break;
2042 		    case( media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "fixedfit" ) ); break;
2043 		    case( media::ZoomLevel_FULLSCREEN ): aZoomValue = OUString( RTL_CONSTASCII_USTRINGPARAM( "fullscreen" ) ); break;
2044 
2045 			default:
2046 			break;
2047 		}
2048 
2049 		if( aZoomValue.getLength() )
2050 		{
2051 			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aZoomStr );
2052 			mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aZoomValue );
2053 			delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, sal_False, sal_True ) );
2054 		}
2055 	}
2056 }
2057