xref: /trunk/main/xmloff/source/draw/shapeexport.cxx (revision 61dff127b6698e0bae836c8aedd6ec62111483d1)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include <memory>
32 
33 #include "unointerfacetouniqueidentifiermapper.hxx"
34 #include <com/sun/star/presentation/ClickAction.hpp>
35 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
36 #include <com/sun/star/container/XChild.hpp>
37 #include <com/sun/star/text/XText.hpp>
38 #include <com/sun/star/chart/XChartDocument.hpp>
39 #include <com/sun/star/drawing/XControlShape.hpp>
40 #include <com/sun/star/style/XStyle.hpp>
41 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
42 #include <com/sun/star/container/XIdentifierAccess.hpp>
43 #include <com/sun/star/drawing/GluePoint2.hpp>
44 #include <com/sun/star/drawing/Alignment.hpp>
45 #include <com/sun/star/drawing/EscapeDirection.hpp>
46 #include <com/sun/star/table/XColumnRowRange.hpp>
47 #include <xmloff/xmluconv.hxx>
48 #include "PropertySetMerger.hxx"
49 
50 #include <xmloff/shapeexport.hxx>
51 #include "sdpropls.hxx"
52 #include "sdxmlexp_impl.hxx"
53 #include <xmloff/families.hxx>
54 #include <tools/debug.hxx>
55 #include <xmloff/contextid.hxx>
56 #include <xmloff/xmltoken.hxx>
57 #include <tools/string.hxx>
58 #include <sot/clsids.hxx>
59 #include <tools/globname.hxx>
60 #include <com/sun/star/beans/XPropertyState.hpp>
61 
62 #include <comphelper/processfactory.hxx>
63 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
64 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
65 
66 #include "xmloff/xmlnmspe.hxx"
67 
68 using ::rtl::OUString;
69 using ::rtl::OUStringBuffer;
70 
71 using namespace ::com::sun::star;
72 using namespace ::xmloff::token;
73 
74 //////////////////////////////////////////////////////////////////////////////
75 
76 XMLShapeExport::XMLShapeExport(SvXMLExport& rExp,
77                                 SvXMLExportPropertyMapper *pExtMapper )
78 :   mrExport( rExp ),
79     mnNextUniqueShapeId(1),
80     maShapesInfos(),
81     maCurrentShapesIter(maShapesInfos.end()),
82     mbExportLayer( sal_False ),
83     // #88546# init to sal_False
84     mbHandleProgressBar( sal_False ),
85     msZIndex( RTL_CONSTASCII_USTRINGPARAM("ZOrder") ),
86     msPrintable( RTL_CONSTASCII_USTRINGPARAM("Printable") ),
87     msVisible( RTL_CONSTASCII_USTRINGPARAM("Visible") ),
88     msEmptyPres( RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") ),
89     msModel( RTL_CONSTASCII_USTRINGPARAM("Model") ),
90     msStartShape( RTL_CONSTASCII_USTRINGPARAM("StartShape") ),
91     msEndShape( RTL_CONSTASCII_USTRINGPARAM("EndShape") ),
92     msOnClick( RTL_CONSTASCII_USTRINGPARAM("OnClick") ),
93 #ifdef ISSUE66550_HLINK_FOR_SHAPES
94     msOnAction( RTL_CONSTASCII_USTRINGPARAM("OnAction") ),
95     msAction( RTL_CONSTASCII_USTRINGPARAM("Action") ),
96     msURL( RTL_CONSTASCII_USTRINGPARAM("URL") ),
97 #endif
98     msEventType( RTL_CONSTASCII_USTRINGPARAM("EventType") ),
99     msPresentation( RTL_CONSTASCII_USTRINGPARAM("Presentation") ),
100     msMacroName( RTL_CONSTASCII_USTRINGPARAM("MacroName") ),
101     msScript( RTL_CONSTASCII_USTRINGPARAM("Script") ),
102     msLibrary( RTL_CONSTASCII_USTRINGPARAM("Library") ),
103     msClickAction( RTL_CONSTASCII_USTRINGPARAM("ClickAction") ),
104     msBookmark( RTL_CONSTASCII_USTRINGPARAM("Bookmark") ),
105     msEffect( RTL_CONSTASCII_USTRINGPARAM("Effect") ),
106     msPlayFull( RTL_CONSTASCII_USTRINGPARAM("PlayFull") ),
107     msVerb( RTL_CONSTASCII_USTRINGPARAM("Verb") ),
108     msSoundURL( RTL_CONSTASCII_USTRINGPARAM("SoundURL") ),
109     msSpeed( RTL_CONSTASCII_USTRINGPARAM("Speed") ),
110     msStarBasic( RTL_CONSTASCII_USTRINGPARAM("StarBasic") )
111 {
112     // construct PropertyHandlerFactory
113     mxSdPropHdlFactory = new XMLSdPropHdlFactory( mrExport.GetModel(), rExp );
114     // construct PropertySetMapper
115     mxPropertySetMapper = CreateShapePropMapper( mrExport );
116     if( pExtMapper )
117     {
118         UniReference < SvXMLExportPropertyMapper > xExtMapper( pExtMapper );
119         mxPropertySetMapper->ChainExportMapper( xExtMapper );
120     }
121 
122 /*
123     // chain text attributes
124     xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp));
125 */
126 
127     mrExport.GetAutoStylePool()->AddFamily(
128         XML_STYLE_FAMILY_SD_GRAPHICS_ID,
129         OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)),
130         GetPropertySetMapper(),
131         OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX)));
132     mrExport.GetAutoStylePool()->AddFamily(
133         XML_STYLE_FAMILY_SD_PRESENTATION_ID,
134         OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_PRESENTATION_NAME)),
135         GetPropertySetMapper(),
136         OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_PRESENTATION_PREFIX)));
137 
138     maCurrentInfo = maShapeInfos.end();
139 
140     // create table export helper and let him add his families in time
141     GetShapeTableExport();
142 }
143 
144 ///////////////////////////////////////////////////////////////////////
145 
146 XMLShapeExport::~XMLShapeExport()
147 {
148 }
149 
150 ///////////////////////////////////////////////////////////////////////
151 
152 // sj: replacing CustomShapes with standard objects that are also supported in OpenOffice.org format
153 uno::Reference< drawing::XShape > XMLShapeExport::checkForCustomShapeReplacement( const uno::Reference< drawing::XShape >& xShape )
154 {
155     uno::Reference< drawing::XShape > xCustomShapeReplacement;
156 
157     if( ( GetExport().getExportFlags() & EXPORT_OASIS ) == 0 )
158     {
159         String aType( (OUString)xShape->getShapeType() );
160         if( aType.EqualsAscii( (const sal_Char*)"com.sun.star.drawing.CustomShape" ) )
161         {
162             uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
163             if( xSet.is() )
164             {
165                 rtl::OUString aEngine;
166                 xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeEngine" ) ) ) >>= aEngine;
167                 if ( !aEngine.getLength() )
168                     aEngine = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) );
169 
170                 uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
171         /*
172                 uno::Reference< drawing::XShape > aXShape = GetXShapeForSdrObject( (SdrObjCustomShape*)pCustomShape );
173                 if ( !aXShape.is() )
174                     aXShape = new SvxCustomShape( (SdrObjCustomShape*)pCustomShape );
175         */
176                 if ( aEngine.getLength() && xFactory.is() )
177                 {
178                     uno::Sequence< uno::Any > aArgument( 1 );
179                     uno::Sequence< beans::PropertyValue > aPropValues( 2 );
180                     aPropValues[ 0 ].Name = rtl::OUString::createFromAscii( "CustomShape" );
181                     aPropValues[ 0 ].Value <<= xShape;
182                     sal_Bool bForceGroupWithText = sal_True;
183                     aPropValues[ 1 ].Name = rtl::OUString::createFromAscii( "ForceGroupWithText" );
184                     aPropValues[ 1 ].Value <<= bForceGroupWithText;
185                     aArgument[ 0 ] <<= aPropValues;
186                     uno::Reference< uno::XInterface > xInterface( xFactory->createInstanceWithArguments( aEngine, aArgument ) );
187                     if ( xInterface.is() )
188                     {
189                         uno::Reference< drawing::XCustomShapeEngine > xCustomShapeEngine(
190                             uno::Reference< drawing::XCustomShapeEngine >( xInterface, uno::UNO_QUERY ) );
191                         if ( xCustomShapeEngine.is() )
192                             xCustomShapeReplacement = xCustomShapeEngine->render();
193                     }
194                 }
195             }
196         }
197     }
198     return xCustomShapeReplacement;
199 }
200 
201 // This method collects all automatic styles for the given XShape
202 void XMLShapeExport::collectShapeAutoStyles(const uno::Reference< drawing::XShape >& xShape )
203 {
204     if( maCurrentShapesIter == maShapesInfos.end() )
205     {
206         DBG_ERROR( "XMLShapeExport::collectShapeAutoStyles(): no call to seekShapes()!" );
207         return;
208     }
209     sal_Int32 nZIndex = 0;
210     uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
211     if( xSet.is() )
212         xSet->getPropertyValue(msZIndex) >>= nZIndex;
213 
214     ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
215 
216     if( (sal_Int32)aShapeInfoVector.size() <= nZIndex )
217     {
218         DBG_ERROR( "XMLShapeExport::collectShapeAutoStyles(): no shape info allocated for a given shape" );
219         return;
220     }
221 
222     ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
223 
224     uno::Reference< drawing::XShape > xCustomShapeReplacement = checkForCustomShapeReplacement( xShape );
225     if ( xCustomShapeReplacement.is() )
226         aShapeInfo.xCustomShapeReplacement = xCustomShapeReplacement;
227 
228     // -----------------------------
229     // first compute the shapes type
230     // -----------------------------
231     ImpCalcShapeType(xShape, aShapeInfo.meShapeType);
232 
233     // #i118485# enabled XmlShapeTypeDrawChartShape and XmlShapeTypeDrawOLE2Shape
234     // to have text
235     const bool bObjSupportsText =
236 //      aShapeInfo.meShapeType != XmlShapeTypeDrawControlShape &&
237         aShapeInfo.meShapeType != XmlShapeTypePresChartShape &&
238         aShapeInfo.meShapeType != XmlShapeTypePresOLE2Shape &&
239         aShapeInfo.meShapeType != XmlShapeTypeDrawSheetShape &&
240         aShapeInfo.meShapeType != XmlShapeTypePresSheetShape &&
241         aShapeInfo.meShapeType != XmlShapeTypeDraw3DSceneObject &&
242         aShapeInfo.meShapeType != XmlShapeTypeDraw3DCubeObject &&
243         aShapeInfo.meShapeType != XmlShapeTypeDraw3DSphereObject &&
244         aShapeInfo.meShapeType != XmlShapeTypeDraw3DLatheObject &&
245         aShapeInfo.meShapeType != XmlShapeTypeDraw3DExtrudeObject &&
246         aShapeInfo.meShapeType != XmlShapeTypeDrawPageShape &&
247         aShapeInfo.meShapeType != XmlShapeTypePresPageShape &&
248         aShapeInfo.meShapeType != XmlShapeTypeDrawGroupShape;
249 
250     const bool bObjSupportsStyle =
251         aShapeInfo.meShapeType != XmlShapeTypeDrawGroupShape;
252 
253     sal_Bool bIsEmptyPresObj = sal_False;
254 
255     uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
256     if ( aShapeInfo.xCustomShapeReplacement.is() )
257         xPropSet.clear();
258 
259     // ----------------
260     // prep text styles
261     // ----------------
262     if( xPropSet.is() && bObjSupportsText )
263     {
264         uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
265         if(xText.is() && xText->getString().getLength())
266         {
267             uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
268 
269             if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(msEmptyPres) )
270             {
271                 uno::Any aAny = xPropSet->getPropertyValue(msEmptyPres);
272                 aAny >>= bIsEmptyPresObj;
273             }
274 
275             if(!bIsEmptyPresObj)
276             {
277                 GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText );
278             }
279         }
280     }
281 
282     // ------------------------------
283     // compute the shape parent style
284     // ------------------------------
285     if( xPropSet.is() )
286     {
287         uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( xPropSet->getPropertySetInfo() );
288 
289         OUString aParentName;
290         uno::Reference< style::XStyle > xStyle;
291 
292         if( bObjSupportsStyle )
293         {
294             if( xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName( OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))) )
295                 xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Style"))) >>= xStyle;
296 
297             if(xStyle.is())
298             {
299                 // get family ID
300                 uno::Reference< beans::XPropertySet > xStylePropSet(xStyle, uno::UNO_QUERY);
301                 DBG_ASSERT( xStylePropSet.is(), "style without a XPropertySet?" );
302                 try
303                 {
304                     if(xStylePropSet.is())
305                     {
306                         OUString aFamilyName;
307                         xStylePropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Family"))) >>= aFamilyName;
308                         if(aFamilyName.getLength() && !aFamilyName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("graphics"))))
309                             aShapeInfo.mnFamily = XML_STYLE_FAMILY_SD_PRESENTATION_ID;
310                     }
311                 }
312                 catch(beans::UnknownPropertyException aException)
313                 {
314                     // Ignored.
315                     DBG_ASSERT(false,
316                         "XMLShapeExport::collectShapeAutoStyles: style has no 'Family' property");
317                 }
318 
319                 // get parent-style name
320                 if(XML_STYLE_FAMILY_SD_PRESENTATION_ID == aShapeInfo.mnFamily)
321                 {
322                     aParentName = msPresentationStylePrefix;
323                 }
324 
325                 aParentName += xStyle->getName();
326             }
327         }
328 
329         // filter propset
330         std::vector< XMLPropertyState > xPropStates;
331 
332         sal_Int32 nCount = 0;
333         if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape)) )
334         {
335             xPropStates = GetPropertySetMapper()->Filter( xPropSet );
336 
337             if (XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType)
338             {
339                 // for control shapes, we additionally need the number format style (if any)
340                 uno::Reference< drawing::XControlShape > xControl(xShape, uno::UNO_QUERY);
341                 DBG_ASSERT(xControl.is(), "XMLShapeExport::collectShapeAutoStyles: ShapeType control, but no XControlShape!");
342                 if (xControl.is())
343                 {
344                     uno::Reference< beans::XPropertySet > xControlModel(xControl->getControl(), uno::UNO_QUERY);
345                     DBG_ASSERT(xControlModel.is(), "XMLShapeExport::collectShapeAutoStyles: no control model on the control shape!");
346 
347                     ::rtl::OUString sNumberStyle = mrExport.GetFormExport()->getControlNumberStyle(xControlModel);
348                     if (0 != sNumberStyle.getLength())
349                     {
350                         sal_Int32 nIndex = GetPropertySetMapper()->getPropertySetMapper()->FindEntryIndex(CTF_SD_CONTROL_SHAPE_DATA_STYLE);
351                             // TODO : this retrieval of the index could be moved into the ctor, holding the index
352                             //          as member, thus saving time.
353                         DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
354 
355                         XMLPropertyState aNewState(nIndex, uno::makeAny(sNumberStyle));
356                         xPropStates.push_back(aNewState);
357                     }
358                 }
359             }
360 
361             std::vector< XMLPropertyState >::iterator aIter = xPropStates.begin();
362             std::vector< XMLPropertyState >::iterator aEnd = xPropStates.end();
363             while( aIter != aEnd )
364             {
365                 if( aIter->mnIndex != -1 )
366                     nCount++;
367                 aIter++;
368             }
369         }
370 
371         if(nCount == 0)
372         {
373             // no hard attributes, use parent style name for export
374             aShapeInfo.msStyleName = aParentName;
375         }
376         else
377         {
378             // there are filtered properties -> hard attributes
379             // try to find this style in AutoStylePool
380             aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Find(aShapeInfo.mnFamily, aParentName, xPropStates);
381 
382             if(!aShapeInfo.msStyleName.getLength())
383             {
384                 // Style did not exist, add it to AutoStalePool
385                 aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Add(aShapeInfo.mnFamily, aParentName, xPropStates);
386             }
387         }
388 
389         // optionaly generate auto style for text attributes
390         if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape)) && bObjSupportsText )
391         {
392             xPropStates = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter( xPropSet );
393 
394             // ----------------------------------------------------------------------
395             // yet more additionally, we need to care for the ParaAdjust property
396             if ( XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType )
397             {
398                 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
399                 uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
400                 if ( xPropSetInfo.is() && xPropState.is() )
401                 {
402                     // this is because:
403                     // * if controls shapes have a ParaAdjust property, then this is the Align property of the control model
404                     // * control models are allowed to have an Align of "void"
405                     // * the Default for control model's Align is TextAlign_LEFT
406                     // * defaults for style properties are not written, but we need to write the "left",
407                     //   because we need to distiguish this "left" from the case where not align attribute
408                     //   is present which means "void"
409                     // 102407 - 2002-11-01 - fs@openoffice.org
410                     static const ::rtl::OUString s_sParaAdjustPropertyName( RTL_CONSTASCII_USTRINGPARAM( "ParaAdjust" ) );
411                     if  (   xPropSetInfo->hasPropertyByName( s_sParaAdjustPropertyName )
412                         &&  ( beans::PropertyState_DEFAULT_VALUE == xPropState->getPropertyState( s_sParaAdjustPropertyName ) )
413                         )
414                     {
415                         sal_Int32 nIndex = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->getPropertySetMapper()->FindEntryIndex( CTF_SD_SHAPE_PARA_ADJUST );
416                             // TODO : this retrieval of the index should be moved into the ctor, holding the index
417                             //          as member, thus saving time.
418                         DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for the ParaAdjust context id!");
419 
420                         uno::Any aParaAdjustValue = xPropSet->getPropertyValue( s_sParaAdjustPropertyName );
421                         XMLPropertyState aAlignDefaultState( nIndex, aParaAdjustValue );
422 
423                         xPropStates.push_back( aAlignDefaultState );
424                     }
425                 }
426             }
427             // ----------------------------------------------------------------------
428 
429             nCount = 0;
430             std::vector< XMLPropertyState >::iterator aIter = xPropStates.begin();
431             std::vector< XMLPropertyState >::iterator aEnd = xPropStates.end();
432             while( aIter != aEnd )
433             {
434                 if( aIter->mnIndex != -1 )
435                     nCount++;
436                 aIter++;
437             }
438 
439             if( nCount )
440             {
441                 const OUString aEmpty;
442                 aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, aEmpty, xPropStates );
443                 if(!aShapeInfo.msTextStyleName.getLength())
444                 {
445                     // Style did not exist, add it to AutoStalePool
446                     aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TEXT_PARAGRAPH, aEmpty, xPropStates);
447                 }
448             }
449         }
450     }
451 
452     // ----------------------------------------
453     // prepare animation informations if needed
454     // ----------------------------------------
455     if( mxAnimationsExporter.is() )
456         mxAnimationsExporter->prepare( xShape, mrExport );
457 
458     // check for special shapes
459 
460     switch( aShapeInfo.meShapeType )
461     {
462         case XmlShapeTypeDrawConnectorShape:
463         {
464             uno::Reference< uno::XInterface > xConnection;
465 
466             // create shape ids for export later
467             xPropSet->getPropertyValue( msStartShape ) >>= xConnection;
468             if( xConnection.is() )
469                 mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );
470 
471             xPropSet->getPropertyValue( msEndShape ) >>= xConnection;
472             if( xConnection.is() )
473                 mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );
474             break;
475         }
476         case XmlShapeTypePresTableShape:
477         case XmlShapeTypeDrawTableShape:
478         {
479             try
480             {
481                 uno::Reference< table::XColumnRowRange > xRange( xSet->getPropertyValue( msModel ), uno::UNO_QUERY_THROW );
482                 GetShapeTableExport()->collectTableAutoStyles( xRange );
483             }
484             catch( uno::Exception& )
485             {
486                 DBG_ERROR( "XMLShapeExport::collectShapeAutoStyles(): exception caught while collection auto styles for a table!" );
487             }
488             break;
489         }
490         default:
491             break;
492     }
493 
494     maShapeInfos.push_back( aShapeInfo );
495     maCurrentInfo = maShapeInfos.begin();
496 
497     // -----------------------------------------------------
498     // check for shape collections (group shape or 3d scene)
499     // and collect contained shapes style infos
500     // -----------------------------------------------------
501     const uno::Reference< drawing::XShape >& xCollection = aShapeInfo.xCustomShapeReplacement.is()
502                                                 ? aShapeInfo.xCustomShapeReplacement : xShape;
503     {
504         uno::Reference< drawing::XShapes > xShapes( xCollection, uno::UNO_QUERY );
505         if( xShapes.is() )
506         {
507             collectShapesAutoStyles( xShapes );
508         }
509     }
510 }
511 
512 ///////////////////////////////////////////////////////////////////////
513 
514 // --> OD 2008-05-08 #refactorlists#
515 namespace
516 {
517     class NewTextListsHelper
518     {
519         public:
520             NewTextListsHelper( SvXMLExport& rExp )
521                 : mrExport( rExp )
522             {
523                 mrExport.GetTextParagraphExport()->PushNewTextListsHelper();
524             }
525 
526             ~NewTextListsHelper()
527             {
528                 mrExport.GetTextParagraphExport()->PopTextListsHelper();
529             }
530 
531         private:
532             SvXMLExport& mrExport;
533     };
534 }
535 // This method exports the given XShape
536 void XMLShapeExport::exportShape(const uno::Reference< drawing::XShape >& xShape,
537                                  sal_Int32 nFeatures /* = SEF_DEFAULT */,
538                                  com::sun::star::awt::Point* pRefPoint /* = NULL */,
539                                  SvXMLAttributeList* pAttrList /* = NULL */ )
540 {
541     if( maCurrentShapesIter == maShapesInfos.end() )
542     {
543         DBG_ERROR( "XMLShapeExport::exportShape(): no auto styles where collected before export" );
544         return;
545     }
546     sal_Int32 nZIndex = 0;
547     uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
548 
549 
550     ::std::auto_ptr< SvXMLElementExport >  mpHyperlinkElement;
551 
552     // export hyperlinks with <a><shape/></a>. Currently only in draw since draw
553     // does not support document events
554     if( xSet.is() && (GetExport().GetModelType() == SvtModuleOptions::E_DRAW) ) try
555     {
556         presentation::ClickAction eAction = presentation::ClickAction_NONE;
557         xSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("OnClick"))) >>= eAction;
558 
559         if( (eAction == presentation::ClickAction_DOCUMENT) ||
560             (eAction == presentation::ClickAction_BOOKMARK) )
561         {
562             OUString sURL;
563             xSet->getPropertyValue(msBookmark) >>= sURL;
564 
565             if( sURL.getLength() )
566             {
567                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );
568                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
569                 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
570                 mpHyperlinkElement.reset( new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_A, sal_True, sal_True) );
571             }
572         }
573     }
574     catch( uno::Exception& )
575     {
576         DBG_ERROR("XMLShapeExport::exportShape(): exception during hyperlink export");
577     }
578 
579 
580     if( xSet.is() )
581         xSet->getPropertyValue(msZIndex) >>= nZIndex;
582 
583     ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
584 
585     if( (sal_Int32)aShapeInfoVector.size() <= nZIndex )
586     {
587         DBG_ERROR( "XMLShapeExport::exportShape(): no shape info collected for a given shape" );
588         return;
589     }
590 
591     // --> OD 2008-05-08 #refactorlists#
592     NewTextListsHelper aNewTextListsHelper( mrExport );
593     // <--
594 
595     const ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
596 
597 
598 #ifdef DBG_UTIL
599     // ---------------------------------------
600     // check if this is the correct ShapesInfo
601     // ---------------------------------------
602     uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY );
603     if( xChild.is() )
604     {
605         uno::Reference< drawing::XShapes > xParent( xChild->getParent(), uno::UNO_QUERY );
606         DBG_ASSERT( xParent.is() && xParent.get() == (*maCurrentShapesIter).first.get(), "XMLShapeExport::exportShape(): Wrong call to XMLShapeExport::seekShapes()" );
607     }
608 
609     // -----------------------------
610     // first compute the shapes type
611     // -----------------------------
612     {
613         XmlShapeType eShapeType(XmlShapeTypeNotYetSet);
614         ImpCalcShapeType(xShape, eShapeType);
615 
616         DBG_ASSERT( eShapeType == aShapeInfo.meShapeType, "exportShape callings do not correspond to collectShapeAutoStyles calls!" );
617     }
618 #endif
619 
620     // ----------------------------------------
621     // collect animation informations if needed
622     // ----------------------------------------
623     if( mxAnimationsExporter.is() )
624         mxAnimationsExporter->collect( xShape, mrExport );
625 
626     // -------------------------------
627     // export shapes name if he has one
628     // --> OD 2006-03-13 #i51726#
629     // Export of the shape name for text documents only if the OpenDocument
630     // file format is written - exceptions are group shapes.
631     // Note: Writer documents in OpenOffice.org file format doesn't contain
632     //       any names for shapes, except for group shapes.
633     // -------------------------------
634     {
635         // --> OD 2006-03-10 #i51726#
636         if ( ( GetExport().GetModelType() != SvtModuleOptions::E_WRITER &&
637                GetExport().GetModelType() != SvtModuleOptions::E_WRITERWEB &&
638                GetExport().GetModelType() != SvtModuleOptions::E_WRITERGLOBAL ) ||
639              ( GetExport().getExportFlags() & EXPORT_OASIS ) != 0 ||
640              aShapeInfo.meShapeType == XmlShapeTypeDrawGroupShape ||
641              ( aShapeInfo.meShapeType == XmlShapeTypeDrawCustomShape &&
642                aShapeInfo.xCustomShapeReplacement.is() ) )
643         {
644             uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
645             if( xNamed.is() )
646             {
647                 const OUString aName( xNamed->getName() );
648                 if( aName.getLength() )
649                     mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, aName );
650             }
651         }
652         // <--
653     }
654 
655     // ------------------
656     // export style name
657     // ------------------
658     if( aShapeInfo.msStyleName.getLength() != 0 )
659     {
660         if(XML_STYLE_FAMILY_SD_GRAPHICS_ID == aShapeInfo.mnFamily)
661             mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
662         else
663             mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
664     }
665 
666     // ------------------
667     // export text style name
668     // ------------------
669     if( aShapeInfo.msTextStyleName.getLength() != 0 )
670     {
671         mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TEXT_STYLE_NAME, aShapeInfo.msTextStyleName );
672     }
673 
674     // --------------------------
675     // export shapes id if needed
676     // --------------------------
677     {
678         uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
679         const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRef );
680         if( rShapeId.getLength() )
681         {
682             mrExport.AddAttributeIdLegacy(XML_NAMESPACE_DRAW, rShapeId);
683         }
684     }
685 
686     // --------------------------
687     // export layer information
688     // --------------------------
689     if( IsLayerExportEnabled() )
690     {
691         // check for group or scene shape and not export layer if this is one
692         uno::Reference< drawing::XShapes > xShapes( xShape, uno::UNO_QUERY );
693         if( !xShapes.is() )
694         {
695             try
696             {
697                 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
698                 OUString aLayerName;
699                 xProps->getPropertyValue( OUString::createFromAscii( "LayerName" ) ) >>= aLayerName;
700                 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LAYER, aLayerName );
701 
702             }
703             catch( uno::Exception e )
704             {
705                 DBG_ERROR( "could not export layer name for shape!" );
706             }
707         }
708     }
709 
710     // export draw:display (do not export in ODF 1.2 or older)
711     if( xSet.is() && ( mrExport.getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) )
712     {
713         if( aShapeInfo.meShapeType != XmlShapeTypeDrawPageShape && aShapeInfo.meShapeType != XmlShapeTypePresPageShape &&
714             aShapeInfo.meShapeType != XmlShapeTypeHandoutShape && aShapeInfo.meShapeType != XmlShapeTypeDrawChartShape )
715 
716         try
717         {
718             sal_Bool bVisible = sal_True;
719             sal_Bool bPrintable = sal_True;
720 
721             xSet->getPropertyValue(msVisible) >>= bVisible;
722             xSet->getPropertyValue(msPrintable) >>= bPrintable;
723 
724             XMLTokenEnum eDisplayToken = XML_TOKEN_INVALID;
725             const unsigned short nDisplay = (bVisible ? 2 : 0) | (bPrintable ? 1 : 0);
726             switch( nDisplay )
727             {
728             case 0: eDisplayToken = XML_NONE; break;
729             case 1: eDisplayToken = XML_PRINTER; break;
730             case 2: eDisplayToken = XML_SCREEN; break;
731             // case 3: eDisplayToken = XML_ALWAYS break; this is the default
732             }
733 
734             if( eDisplayToken != XML_TOKEN_INVALID )
735                 mrExport.AddAttribute(XML_NAMESPACE_DRAW_EXT, XML_DISPLAY, eDisplayToken );
736         }
737         catch( uno::Exception& )
738         {
739             DBG_ERROR( "XMLShapeExport::exportShape(), exception caught!" );
740         }
741     }
742 
743     // #82003# test export count
744     // #91587# ALWAYS increment since now ALL to be exported shapes are counted.
745     if(mrExport.GetShapeExport()->IsHandleProgressBarEnabled())
746     {
747         mrExport.GetProgressBarHelper()->Increment();
748     }
749 
750     onExport( xShape );
751 
752     // --------------------
753     // export shape element
754     // --------------------
755     switch(aShapeInfo.meShapeType)
756     {
757         case XmlShapeTypeDrawRectangleShape:
758         {
759             ImpExportRectangleShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
760             break;
761         }
762         case XmlShapeTypeDrawEllipseShape:
763         {
764             ImpExportEllipseShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
765             break;
766         }
767         case XmlShapeTypeDrawLineShape:
768         {
769             ImpExportLineShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
770             break;
771         }
772         case XmlShapeTypeDrawPolyPolygonShape:  // closed PolyPolygon
773         case XmlShapeTypeDrawPolyLineShape:     // open PolyPolygon
774         case XmlShapeTypeDrawClosedBezierShape: // closed PolyPolygon containing curves
775         case XmlShapeTypeDrawOpenBezierShape:   // open PolyPolygon containing curves
776         {
777             ImpExportPolygonShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
778             break;
779         }
780 
781         case XmlShapeTypeDrawTextShape:
782         case XmlShapeTypePresTitleTextShape:
783         case XmlShapeTypePresOutlinerShape:
784         case XmlShapeTypePresSubtitleShape:
785         case XmlShapeTypePresNotesShape:
786         case XmlShapeTypePresHeaderShape:
787         case XmlShapeTypePresFooterShape:
788         case XmlShapeTypePresSlideNumberShape:
789         case XmlShapeTypePresDateTimeShape:
790         {
791             ImpExportTextBoxShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
792             break;
793         }
794 
795         case XmlShapeTypeDrawGraphicObjectShape:
796         case XmlShapeTypePresGraphicObjectShape:
797         {
798             ImpExportGraphicObjectShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
799             break;
800         }
801 
802         case XmlShapeTypeDrawChartShape:
803         case XmlShapeTypePresChartShape:
804         {
805             ImpExportChartShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint, pAttrList );
806             break;
807         }
808 
809         case XmlShapeTypeDrawControlShape:
810         {
811             ImpExportControlShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
812             break;
813         }
814 
815         case XmlShapeTypeDrawConnectorShape:
816         {
817             ImpExportConnectorShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
818             break;
819         }
820 
821         case XmlShapeTypeDrawMeasureShape:
822         {
823             ImpExportMeasureShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
824             break;
825         }
826 
827         case XmlShapeTypeDrawOLE2Shape:
828         case XmlShapeTypePresOLE2Shape:
829         case XmlShapeTypeDrawSheetShape:
830         case XmlShapeTypePresSheetShape:
831         {
832             ImpExportOLE2Shape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
833             break;
834         }
835 
836         case XmlShapeTypePresTableShape:
837         case XmlShapeTypeDrawTableShape:
838         {
839             ImpExportTableShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
840             break;
841         }
842 
843         case XmlShapeTypeDrawPageShape:
844         case XmlShapeTypePresPageShape:
845         case XmlShapeTypeHandoutShape:
846         {
847             ImpExportPageShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
848             break;
849         }
850 
851         case XmlShapeTypeDrawCaptionShape:
852         {
853             ImpExportCaptionShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
854             break;
855         }
856 
857         case XmlShapeTypeDraw3DCubeObject:
858         case XmlShapeTypeDraw3DSphereObject:
859         case XmlShapeTypeDraw3DLatheObject:
860         case XmlShapeTypeDraw3DExtrudeObject:
861         {
862             ImpExport3DShape(xShape, aShapeInfo.meShapeType);
863             break;
864         }
865 
866         case XmlShapeTypeDraw3DSceneObject:
867         {
868             ImpExport3DSceneShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
869             break;
870         }
871 
872         case XmlShapeTypeDrawGroupShape:
873         {
874             // empty group
875             ImpExportGroupShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
876             break;
877         }
878 
879         case XmlShapeTypeDrawFrameShape:
880         {
881             ImpExportFrameShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
882             break;
883         }
884 
885         case XmlShapeTypeDrawAppletShape:
886         {
887             ImpExportAppletShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
888             break;
889         }
890 
891         case XmlShapeTypeDrawPluginShape:
892         {
893             ImpExportPluginShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
894             break;
895         }
896 
897         case XmlShapeTypeDrawCustomShape:
898         {
899             if ( aShapeInfo.xCustomShapeReplacement.is() )
900                 ImpExportGroupShape( aShapeInfo.xCustomShapeReplacement, XmlShapeTypeDrawGroupShape, nFeatures, pRefPoint );
901             else
902                 ImpExportCustomShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
903             break;
904         }
905 
906         case XmlShapeTypePresMediaShape:
907         case XmlShapeTypeDrawMediaShape:
908         {
909             ImpExportMediaShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
910             break;
911         }
912 
913         case XmlShapeTypePresOrgChartShape:
914         case XmlShapeTypeUnknown:
915         case XmlShapeTypeNotYetSet:
916         default:
917         {
918             // this should never happen and is an error
919             DBG_ERROR("XMLEXP: WriteShape: unknown or unexpected type of shape in export!");
920             break;
921         }
922     }
923 
924     mpHyperlinkElement.reset();
925 
926     // #97489# #97111#
927     // if there was an error and no element for the shape was exported
928     // we need to clear the attribute list or the attributes will be
929     // set on the next exported element, which can result in corrupt
930     // xml files due to duplicate attributes
931 
932     mrExport.CheckAttrList();   // asserts in non pro if we have attributes left
933     mrExport.ClearAttrList();   // clears the attributes
934 }
935 
936 ///////////////////////////////////////////////////////////////////////
937 
938 // This method collects all automatic styles for the shapes inside the given XShapes collection
939 void XMLShapeExport::collectShapesAutoStyles( const uno::Reference < drawing::XShapes >& xShapes )
940 {
941     ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
942     seekShapes( xShapes );
943 
944     uno::Reference< drawing::XShape > xShape;
945     const sal_Int32 nShapeCount(xShapes->getCount());
946     for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
947     {
948         xShapes->getByIndex(nShapeId) >>= xShape;
949         DBG_ASSERT( xShape.is(), "Shape without a XShape?" );
950         if(!xShape.is())
951             continue;
952 
953         collectShapeAutoStyles( xShape );
954     }
955 
956     maCurrentShapesIter = aOldCurrentShapesIter;
957 }
958 
959 ///////////////////////////////////////////////////////////////////////
960 
961 // This method exports all XShape inside the given XShapes collection
962 void XMLShapeExport::exportShapes( const uno::Reference < drawing::XShapes >& xShapes, sal_Int32 nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */ )
963 {
964     ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
965     seekShapes( xShapes );
966 
967     uno::Reference< drawing::XShape > xShape;
968     const sal_Int32 nShapeCount(xShapes->getCount());
969     for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
970     {
971         xShapes->getByIndex(nShapeId) >>= xShape;
972         DBG_ASSERT( xShape.is(), "Shape without a XShape?" );
973         if(!xShape.is())
974             continue;
975 
976         exportShape( xShape, nFeatures, pRefPoint );
977     }
978 
979     maCurrentShapesIter = aOldCurrentShapesIter;
980 }
981 
982 ///////////////////////////////////////////////////////////////////////
983 
984 void XMLShapeExport::seekShapes( const uno::Reference< drawing::XShapes >& xShapes ) throw()
985 {
986     if( xShapes.is() )
987     {
988         maCurrentShapesIter = maShapesInfos.find( xShapes );
989         if( maCurrentShapesIter == maShapesInfos.end() )
990         {
991             ImplXMLShapeExportInfoVector aNewInfoVector;
992             aNewInfoVector.resize( (ShapesInfos::size_type) xShapes->getCount() );
993             maShapesInfos[ xShapes ] = aNewInfoVector;
994 
995             maCurrentShapesIter = maShapesInfos.find( xShapes );
996 
997             DBG_ASSERT( maCurrentShapesIter != maShapesInfos.end(), "XMLShapeExport::seekShapes(): insert into stl::map failed" );
998         }
999 
1000         DBG_ASSERT( (*maCurrentShapesIter).second.size() == (ShapesInfos::size_type)xShapes->getCount(), "XMLShapeExport::seekShapes(): XShapes size varied between calls" );
1001 
1002     }
1003     else
1004     {
1005         maCurrentShapesIter = maShapesInfos.end();
1006     }
1007 }
1008 
1009 ///////////////////////////////////////////////////////////////////////
1010 
1011 void XMLShapeExport::exportAutoStyles()
1012 {
1013     // export all autostyle infos
1014 
1015     // ...for graphic
1016 //  if(IsFamilyGraphicUsed())
1017     {
1018         GetExport().GetAutoStylePool()->exportXML(
1019             XML_STYLE_FAMILY_SD_GRAPHICS_ID
1020             , GetExport().GetDocHandler(),
1021             GetExport().GetMM100UnitConverter(),
1022             GetExport().GetNamespaceMap()
1023             );
1024     }
1025 
1026     // ...for presentation
1027 //  if(IsFamilyPresentationUsed())
1028     {
1029         GetExport().GetAutoStylePool()->exportXML(
1030             XML_STYLE_FAMILY_SD_PRESENTATION_ID
1031             , GetExport().GetDocHandler(),
1032             GetExport().GetMM100UnitConverter(),
1033             GetExport().GetNamespaceMap()
1034             );
1035     }
1036 
1037     if( mxShapeTableExport.is() )
1038         mxShapeTableExport->exportAutoStyles();
1039 }
1040 
1041 ///////////////////////////////////////////////////////////////////////
1042 
1043 /// returns the export property mapper for external chaining
1044 SvXMLExportPropertyMapper* XMLShapeExport::CreateShapePropMapper(
1045     SvXMLExport& rExport )
1046 {
1047     UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rExport.GetModel(), rExport );
1048     UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory );
1049     SvXMLExportPropertyMapper* pResult =
1050         new XMLShapeExportPropertyMapper( xMapper,
1051                                           (XMLTextListAutoStylePool*)&rExport.GetTextParagraphExport()->GetListAutoStylePool(),
1052                                           rExport );
1053     // chain text attributes
1054     return pResult;
1055 }
1056 
1057 ///////////////////////////////////////////////////////////////////////
1058 
1059 void XMLShapeExport::ImpCalcShapeType(const uno::Reference< drawing::XShape >& xShape,
1060     XmlShapeType& eShapeType)
1061 {
1062     // set in every case, so init here
1063     eShapeType = XmlShapeTypeUnknown;
1064 
1065     uno::Reference< drawing::XShapeDescriptor > xShapeDescriptor(xShape, uno::UNO_QUERY);
1066     if(xShapeDescriptor.is())
1067     {
1068         String aType((OUString)xShapeDescriptor->getShapeType());
1069 
1070         if(aType.EqualsAscii((const sal_Char*)"com.sun.star.", 0, 13))
1071         {
1072             if(aType.EqualsAscii("drawing.", 13, 8))
1073             {
1074                 // drawing shapes
1075                 if     (aType.EqualsAscii("Rectangle", 21, 9)) { eShapeType = XmlShapeTypeDrawRectangleShape; }
1076 
1077                 // #i72177# Note: Correcting CustomShape, CustomShape->Custom, len from 9 (was wrong anyways) to 6.
1078                 // As can be seen at the other compares, the appendix "Shape" is left out of the comparison.
1079                 else if(aType.EqualsAscii("Custom", 21, 6)) { eShapeType = XmlShapeTypeDrawCustomShape; }
1080 
1081                 else if(aType.EqualsAscii("Ellipse", 21, 7)) { eShapeType = XmlShapeTypeDrawEllipseShape; }
1082                 else if(aType.EqualsAscii("Control", 21, 7)) { eShapeType = XmlShapeTypeDrawControlShape; }
1083                 else if(aType.EqualsAscii("Connector", 21, 9)) { eShapeType = XmlShapeTypeDrawConnectorShape; }
1084                 else if(aType.EqualsAscii("Measure", 21, 7)) { eShapeType = XmlShapeTypeDrawMeasureShape; }
1085                 else if(aType.EqualsAscii("Line", 21, 4)) { eShapeType = XmlShapeTypeDrawLineShape; }
1086 
1087                 // #i72177# Note: This covers two types by purpose, PolyPolygonShape and PolyPolygonPathShape
1088                 else if(aType.EqualsAscii("PolyPolygon", 21, 11)) { eShapeType = XmlShapeTypeDrawPolyPolygonShape; }
1089 
1090                 // #i72177# Note: This covers two types by purpose, PolyLineShape and PolyLinePathShape
1091                 else if(aType.EqualsAscii("PolyLine", 21, 8)) { eShapeType = XmlShapeTypeDrawPolyLineShape; }
1092 
1093                 else if(aType.EqualsAscii("OpenBezier", 21, 10)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
1094                 else if(aType.EqualsAscii("ClosedBezier", 21, 12)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }
1095 
1096                 // #i72177# FreeHand (opened and closed) now supports the types OpenFreeHandShape and
1097                 // ClosedFreeHandShape respectively. Represent them as bezier shapes
1098                 else if(aType.EqualsAscii("OpenFreeHand", 21, 12)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
1099                 else if(aType.EqualsAscii("ClosedFreeHand", 21, 14)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }
1100 
1101                 else if(aType.EqualsAscii("GraphicObject", 21, 13)) { eShapeType = XmlShapeTypeDrawGraphicObjectShape; }
1102                 else if(aType.EqualsAscii("Group", 21, 5)) { eShapeType = XmlShapeTypeDrawGroupShape; }
1103                 else if(aType.EqualsAscii("Text", 21, 4)) { eShapeType = XmlShapeTypeDrawTextShape; }
1104                 else if(aType.EqualsAscii("OLE2", 21, 4))
1105                 {
1106                     eShapeType = XmlShapeTypeDrawOLE2Shape;
1107 
1108                     // get info about presentation shape
1109                     uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1110 
1111                     if(xPropSet.is())
1112                     {
1113                         rtl::OUString sCLSID;
1114                         if(xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID"))) >>= sCLSID)
1115                         {
1116                             if (sCLSID.equals(mrExport.GetChartExport()->getChartCLSID()))
1117                             {
1118                                 eShapeType = XmlShapeTypeDrawChartShape;
1119                             }
1120                             else if (
1121                                 sCLSID.equals(rtl::OUString( SvGlobalName( SO3_SC_CLASSID ).GetHexName()))
1122                                 // #110680#
1123                                 // same reaction for binfilter
1124                                 || sCLSID.equals(rtl::OUString( SvGlobalName( BF_SO3_SC_CLASSID ).GetHexName()))
1125                                 )
1126                             {
1127                                 eShapeType = XmlShapeTypeDrawSheetShape;
1128                             }
1129                             else
1130                             {
1131                                 // general OLE2 Object
1132                             }
1133                         }
1134                     }
1135                 }
1136                 else if(aType.EqualsAscii("Page", 21, 4)) { eShapeType = XmlShapeTypeDrawPageShape; }
1137                 else if(aType.EqualsAscii("Frame", 21, 5)) { eShapeType = XmlShapeTypeDrawFrameShape; }
1138                 else if(aType.EqualsAscii("Caption", 21, 7)) { eShapeType = XmlShapeTypeDrawCaptionShape; }
1139                 else if(aType.EqualsAscii("Plugin", 21, 6)) { eShapeType = XmlShapeTypeDrawPluginShape; }
1140                 else if(aType.EqualsAscii("Applet", 21, 6)) { eShapeType = XmlShapeTypeDrawAppletShape; }
1141                 else if(aType.EqualsAscii("MediaShape", 21, 10)) { eShapeType = XmlShapeTypeDrawMediaShape; }
1142                 else if(aType.EqualsAscii("TableShape", 21, 10)) { eShapeType = XmlShapeTypeDrawTableShape; }
1143 
1144                 // 3D shapes
1145                 else if(aType.EqualsAscii("Scene", 21 + 7, 5)) { eShapeType = XmlShapeTypeDraw3DSceneObject; }
1146                 else if(aType.EqualsAscii("Cube", 21 + 7, 4)) { eShapeType = XmlShapeTypeDraw3DCubeObject; }
1147                 else if(aType.EqualsAscii("Sphere", 21 + 7, 6)) { eShapeType = XmlShapeTypeDraw3DSphereObject; }
1148                 else if(aType.EqualsAscii("Lathe", 21 + 7, 5)) { eShapeType = XmlShapeTypeDraw3DLatheObject; }
1149                 else if(aType.EqualsAscii("Extrude", 21 + 7, 7)) { eShapeType = XmlShapeTypeDraw3DExtrudeObject; }
1150             }
1151             else if(aType.EqualsAscii("presentation.", 13, 13))
1152             {
1153                 // presentation shapes
1154                 if     (aType.EqualsAscii("TitleText", 26, 9)) { eShapeType = XmlShapeTypePresTitleTextShape; }
1155                 else if(aType.EqualsAscii("Outliner", 26, 8)) { eShapeType = XmlShapeTypePresOutlinerShape;  }
1156                 else if(aType.EqualsAscii("Subtitle", 26, 8)) { eShapeType = XmlShapeTypePresSubtitleShape;  }
1157                 else if(aType.EqualsAscii("GraphicObject", 26, 13)) { eShapeType = XmlShapeTypePresGraphicObjectShape;  }
1158                 else if(aType.EqualsAscii("Page", 26, 4)) { eShapeType = XmlShapeTypePresPageShape;  }
1159                 else if(aType.EqualsAscii("OLE2", 26, 4))
1160                 {
1161                     eShapeType = XmlShapeTypePresOLE2Shape;
1162 
1163                     // get info about presentation shape
1164                     uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1165 
1166                     if(xPropSet.is()) try
1167                     {
1168                         rtl::OUString sCLSID;
1169                         if(xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CLSID"))) >>= sCLSID)
1170                         {
1171                             if( sCLSID.equals(rtl::OUString( SvGlobalName( SO3_SC_CLASSID ).GetHexName())) ||
1172                                 sCLSID.equals(rtl::OUString( SvGlobalName( BF_SO3_SC_CLASSID ).GetHexName())) )
1173                             {
1174                                 eShapeType = XmlShapeTypePresSheetShape;
1175                             }
1176                         }
1177                     }
1178                     catch( uno::Exception& )
1179                     {
1180                         DBG_ERROR( "XMLShapeExport::ImpCalcShapeType(), expected ole shape to have the CLSID property?" );
1181                     }
1182                 }
1183                 else if(aType.EqualsAscii("Chart", 26, 5)) { eShapeType = XmlShapeTypePresChartShape;  }
1184                 else if(aType.EqualsAscii("OrgChart", 26, 8)) { eShapeType = XmlShapeTypePresOrgChartShape;  }
1185                 else if(aType.EqualsAscii("CalcShape", 26, 9)) { eShapeType = XmlShapeTypePresSheetShape; }
1186                 else if(aType.EqualsAscii("TableShape", 26, 10)) { eShapeType = XmlShapeTypePresTableShape; }
1187                 else if(aType.EqualsAscii("Notes", 26, 5)) { eShapeType = XmlShapeTypePresNotesShape;  }
1188                 else if(aType.EqualsAscii("HandoutShape", 26, 12)) { eShapeType = XmlShapeTypeHandoutShape; }
1189                 else if(aType.EqualsAscii("HeaderShape", 26, 11)) { eShapeType = XmlShapeTypePresHeaderShape; }
1190                 else if(aType.EqualsAscii("FooterShape", 26, 11)) { eShapeType = XmlShapeTypePresFooterShape; }
1191                 else if(aType.EqualsAscii("SlideNumberShape", 26, 16)) { eShapeType = XmlShapeTypePresSlideNumberShape; }
1192                 else if(aType.EqualsAscii("DateTimeShape", 26, 13)) { eShapeType = XmlShapeTypePresDateTimeShape; }
1193                 else if(aType.EqualsAscii("MediaShape", 26, 10)) { eShapeType = XmlShapeTypePresMediaShape; }
1194             }
1195         }
1196     }
1197 }
1198 
1199 ///////////////////////////////////////////////////////////////////////
1200 
1201 extern SvXMLEnumMapEntry aXML_GlueAlignment_EnumMap[];
1202 extern SvXMLEnumMapEntry aXML_GlueEscapeDirection_EnumMap[];
1203 
1204 /** exports all user defined glue points */
1205 void XMLShapeExport::ImpExportGluePoints( const uno::Reference< drawing::XShape >& xShape )
1206 {
1207     uno::Reference< drawing::XGluePointsSupplier > xSupplier( xShape, uno::UNO_QUERY );
1208     if( !xSupplier.is() )
1209         return;
1210 
1211     uno::Reference< container::XIdentifierAccess > xGluePoints( xSupplier->getGluePoints(), uno::UNO_QUERY );
1212     if( !xGluePoints.is() )
1213         return;
1214 
1215     drawing::GluePoint2 aGluePoint;
1216 
1217     uno::Sequence< sal_Int32 > aIdSequence( xGluePoints->getIdentifiers() );
1218 
1219     const sal_Int32 nCount = aIdSequence.getLength();
1220     for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
1221     {
1222         const sal_Int32 nIdentifier = aIdSequence[nIndex];
1223         if( (xGluePoints->getByIdentifier( nIdentifier ) >>= aGluePoint) && aGluePoint.IsUserDefined )
1224         {
1225             // export only user defined glue points
1226 
1227             const OUString sId( OUString::valueOf( nIdentifier ) );
1228             mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_ID, sId );
1229 
1230             mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aGluePoint.Position.X);
1231             mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, msBuffer.makeStringAndClear());
1232 
1233             mrExport.GetMM100UnitConverter().convertMeasure(msBuffer, aGluePoint.Position.Y);
1234             mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, msBuffer.makeStringAndClear());
1235 
1236             if( !aGluePoint.IsRelative )
1237             {
1238                 SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.PositionAlignment, aXML_GlueAlignment_EnumMap );
1239                 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ALIGN, msBuffer.makeStringAndClear() );
1240             }
1241 
1242             if( aGluePoint.Escape != drawing::EscapeDirection_SMART )
1243             {
1244                 SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.Escape, aXML_GlueEscapeDirection_EnumMap );
1245                 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ESCAPE_DIRECTION, msBuffer.makeStringAndClear() );
1246             }
1247 
1248             SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_DRAW, XML_GLUE_POINT, sal_True, sal_True);
1249         }
1250     }
1251 }
1252 
1253 void XMLShapeExport::ExportGraphicDefaults()
1254 {
1255     XMLStyleExport aStEx(mrExport, OUString(), mrExport.GetAutoStylePool().get());
1256 
1257     // construct PropertySetMapper
1258     UniReference< SvXMLExportPropertyMapper > xPropertySetMapper( CreateShapePropMapper( mrExport ) );
1259     ((XMLShapeExportPropertyMapper*)xPropertySetMapper.get())->SetAutoStyles( sal_False );
1260 
1261     // chain text attributes
1262     xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(mrExport));
1263 
1264     // chain special Writer/text frame default attributes
1265     xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaDefaultExtPropMapper(mrExport));
1266 
1267     // write graphic family default style
1268     uno::Reference< lang::XMultiServiceFactory > xFact( mrExport.GetModel(), uno::UNO_QUERY );
1269     if( xFact.is() )
1270     {
1271         try
1272         {
1273             uno::Reference< beans::XPropertySet > xDefaults( xFact->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.Defaults") ) ), uno::UNO_QUERY );
1274             if( xDefaults.is() )
1275             {
1276                 aStEx.exportDefaultStyle( xDefaults, OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), xPropertySetMapper );
1277 
1278                 // write graphic family styles
1279                 aStEx.exportStyleFamily("graphics", OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_SD_GRAPHICS_NAME)), xPropertySetMapper, sal_False, XML_STYLE_FAMILY_SD_GRAPHICS_ID);
1280             }
1281         }
1282         catch( lang::ServiceNotRegisteredException& )
1283         {
1284         }
1285     }
1286 }
1287 
1288 void XMLShapeExport::onExport( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& )
1289 {
1290 }
1291 
1292 const rtl::Reference< XMLTableExport >& XMLShapeExport::GetShapeTableExport()
1293 {
1294     if( !mxShapeTableExport.is() )
1295     {
1296         rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrExport.GetModel(), mrExport ) );
1297         UniReference < XMLPropertySetMapper > xMapper( new XMLShapePropertySetMapper( xFactory.get() ) );
1298         rtl::Reference< SvXMLExportPropertyMapper > xPropertySetMapper( new XMLShapeExportPropertyMapper( xMapper, (XMLTextListAutoStylePool*)&mrExport.GetTextParagraphExport()->GetListAutoStylePool(), mrExport ) );
1299         mxShapeTableExport = new XMLTableExport( mrExport, xPropertySetMapper, xFactory );
1300     }
1301 
1302     return mxShapeTableExport;
1303 }
1304