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