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