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