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