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