merge the formfield patch from ooo-build
[ooovba.git] / xmloff / source / draw / eventimp.cxx
blob737fbcd86996f958dfe63937bea4a495cdcfc220
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventimp.cxx,v $
10 * $Revision: 1.17 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include <tools/debug.hxx>
35 #include <com/sun/star/document/XEventsSupplier.hpp>
36 #include <com/sun/star/container/XNameReplace.hpp>
37 #include <com/sun/star/presentation/AnimationSpeed.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/xml/sax/XAttributeList.hpp>
40 #include <com/sun/star/presentation/ClickAction.hpp>
41 #include <tools/urlobj.hxx>
42 #include <comphelper/extract.hxx>
43 #include <xmloff/xmltoken.hxx>
44 #include <xmloff/xmlimp.hxx>
45 #include "xmlnmspe.hxx"
46 #include <xmloff/xmluconv.hxx>
47 #include <xmloff/nmspmap.hxx>
48 #include "eventimp.hxx"
49 #include "anim.hxx"
51 using ::rtl::OUString;
52 using ::rtl::OUStringBuffer;
54 using namespace ::std;
55 using namespace ::cppu;
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::xml;
58 using namespace ::com::sun::star::xml::sax;
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::drawing;
61 using namespace ::com::sun::star::beans;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::document;
64 using namespace ::com::sun::star::container;
65 using namespace ::com::sun::star::presentation;
66 using namespace ::xmloff::token;
68 ///////////////////////////////////////////////////////////////////////
70 SvXMLEnumMapEntry __READONLY_DATA aXML_EventActions_EnumMap[] =
72 { XML_NONE, ClickAction_NONE },
73 { XML_PREVIOUS_PAGE, ClickAction_PREVPAGE },
74 { XML_NEXT_PAGE, ClickAction_NEXTPAGE },
75 { XML_FIRST_PAGE, ClickAction_FIRSTPAGE },
76 { XML_LAST_PAGE, ClickAction_LASTPAGE },
77 { XML_HIDE, ClickAction_INVISIBLE },
78 { XML_STOP, ClickAction_STOPPRESENTATION },
79 { XML_EXECUTE, ClickAction_PROGRAM },
80 { XML_SHOW, ClickAction_BOOKMARK },
81 { XML_SHOW, ClickAction_DOCUMENT },
82 { XML_EXECUTE_MACRO, ClickAction_MACRO },
83 { XML_VERB, ClickAction_VERB },
84 { XML_FADE_OUT, ClickAction_VANISH },
85 { XML_SOUND, ClickAction_SOUND },
86 { XML_TOKEN_INVALID, 0 }
89 ///////////////////////////////////////////////////////////////////////
91 class SdXMLEventContext : public SvXMLImportContext
93 private:
94 com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxShape;
96 public:
97 TYPEINFO();
99 SdXMLEventContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLocalName, const Reference< XAttributeList>& xAttrList, const Reference< XShape >& rxShape );
100 virtual ~SdXMLEventContext();
102 virtual SvXMLImportContext * CreateChildContext( USHORT nPrefix, const OUString& rLocalName, const Reference< XAttributeList>& xAttrList );
103 virtual void EndElement();
105 sal_Bool mbValid;
106 sal_Bool mbScript;
107 ClickAction meClickAction;
108 XMLEffect meEffect;
109 XMLEffectDirection meDirection;
110 sal_Int16 mnStartScale;
111 AnimationSpeed meSpeed;
112 sal_Int32 mnVerb;
113 OUString msSoundURL;
114 sal_Bool mbPlayFull;
115 OUString msMacroName;
116 OUString msBookmark;
117 OUString msLanguage;
120 ///////////////////////////////////////////////////////////////////////
122 class XMLEventSoundContext : public SvXMLImportContext
124 SdXMLEventContext* mpParent;
126 public:
127 TYPEINFO();
129 XMLEventSoundContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList, SdXMLEventContext* pParent );
130 virtual ~XMLEventSoundContext();
133 TYPEINIT1( XMLEventSoundContext, SvXMLImportContext );
135 XMLEventSoundContext::XMLEventSoundContext( SvXMLImport& rImp, sal_uInt16 nPrfx, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList, SdXMLEventContext* pParent )
136 : SvXMLImportContext( rImp, nPrfx, rLocalName ), mpParent( pParent )
138 if( mpParent && nPrfx == XML_NAMESPACE_PRESENTATION && IsXMLToken( rLocalName, XML_SOUND ) )
140 const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
141 for(sal_Int16 i=0; i < nAttrCount; i++)
143 OUString sAttrName = xAttrList->getNameByIndex( i );
144 OUString aAttrLocalName;
145 sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aAttrLocalName );
146 OUString sValue = xAttrList->getValueByIndex( i );
148 switch( nAttrPrefix )
150 case XML_NAMESPACE_XLINK:
151 if( IsXMLToken( aAttrLocalName, XML_HREF ) )
153 mpParent->msSoundURL = rImp.GetAbsoluteReference(sValue);
155 break;
156 case XML_NAMESPACE_PRESENTATION:
157 if( IsXMLToken( aAttrLocalName, XML_PLAY_FULL ) )
159 mpParent->mbPlayFull = IsXMLToken( sValue, XML_TRUE );
166 XMLEventSoundContext::~XMLEventSoundContext()
170 ///////////////////////////////////////////////////////////////////////
172 TYPEINIT1( SdXMLEventContext, SvXMLImportContext );
174 SdXMLEventContext::SdXMLEventContext( SvXMLImport& rImp, sal_uInt16 nPrfx, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList, const Reference< XShape >& rxShape )
175 : SvXMLImportContext(rImp, nPrfx, rLocalName),
176 mxShape( rxShape ), mbScript( sal_False ), meClickAction( ClickAction_NONE ),
177 meEffect( EK_none ), meDirection( ED_none ), mnStartScale( 100 ),
178 meSpeed( AnimationSpeed_MEDIUM ), mnVerb(0), mbPlayFull( sal_False )
180 static const OUString sXMLClickName( RTL_CONSTASCII_USTRINGPARAM( "click" ) );
182 if( nPrfx == XML_NAMESPACE_PRESENTATION && IsXMLToken( rLocalName, XML_EVENT_LISTENER ) )
184 mbValid = sal_True;
186 else if( nPrfx == XML_NAMESPACE_SCRIPT && IsXMLToken( rLocalName, XML_EVENT_LISTENER ) )
188 mbScript = sal_True;
189 mbValid = sal_True;
191 else
193 return;
196 // read attributes
197 OUString sEventName;
198 const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
199 for(sal_Int16 i=0; (i < nAttrCount) && mbValid; i++)
201 OUString sAttrName = xAttrList->getNameByIndex( i );
202 OUString aAttrLocalName;
203 sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aAttrLocalName );
204 OUString sValue = xAttrList->getValueByIndex( i );
206 switch( nAttrPrefix )
208 case XML_NAMESPACE_PRESENTATION:
209 if( IsXMLToken( aAttrLocalName, XML_ACTION ) )
211 USHORT eEnum;
212 if( SvXMLUnitConverter::convertEnum( eEnum, sValue, aXML_EventActions_EnumMap ) )
213 meClickAction = (ClickAction)eEnum;
215 if( IsXMLToken( aAttrLocalName, XML_EFFECT ) )
217 USHORT eEnum;
218 if( SvXMLUnitConverter::convertEnum( eEnum, sValue, aXML_AnimationEffect_EnumMap ) )
219 meEffect = (XMLEffect)eEnum;
221 else if( IsXMLToken( aAttrLocalName, XML_DIRECTION ) )
223 USHORT eEnum;
224 if( SvXMLUnitConverter::convertEnum( eEnum, sValue, aXML_AnimationDirection_EnumMap ) )
225 meDirection = (XMLEffectDirection)eEnum;
227 else if( IsXMLToken( aAttrLocalName, XML_START_SCALE ) )
229 sal_Int32 nScale;
230 if( SvXMLUnitConverter::convertPercent( nScale, sValue ) )
231 mnStartScale = (sal_Int16)nScale;
233 else if( IsXMLToken( aAttrLocalName, XML_SPEED ) )
235 USHORT eEnum;
236 if( SvXMLUnitConverter::convertEnum( eEnum, sValue, aXML_AnimationSpeed_EnumMap ) )
237 meSpeed = (AnimationSpeed)eEnum;
239 else if( IsXMLToken( aAttrLocalName, XML_VERB ) )
241 SvXMLUnitConverter::convertNumber( mnVerb, sValue );
243 break;
245 case XML_NAMESPACE_SCRIPT:
246 if( IsXMLToken( aAttrLocalName, XML_EVENT_NAME ) )
248 sEventName = sValue;
249 sal_uInt16 nScriptPrefix =
250 GetImport().GetNamespaceMap().GetKeyByAttrName( sValue, &sEventName );
251 mbValid = XML_NAMESPACE_DOM == nScriptPrefix && sEventName == sXMLClickName;
253 else if( IsXMLToken( aAttrLocalName, XML_LANGUAGE ) )
255 // language is not evaluated!
256 OUString aScriptLanguage;
257 msLanguage = sValue;
258 sal_uInt16 nScriptPrefix = rImp.GetNamespaceMap().
259 GetKeyByAttrName( msLanguage, &aScriptLanguage );
260 if( XML_NAMESPACE_OOO == nScriptPrefix )
261 msLanguage = aScriptLanguage;
263 else if( IsXMLToken( aAttrLocalName, XML_MACRO_NAME ) )
265 msMacroName = sValue;
267 // else if( IsXMLToken( aLocalName, XML_LIBRARY ) )
268 // {
269 // msLibrary = sValue;
270 // }
271 break;
273 case XML_NAMESPACE_XLINK:
274 if( IsXMLToken( aAttrLocalName, XML_HREF ) )
276 if ( mbScript )
278 msMacroName = sValue;
280 else
282 const rtl::OUString &rTmp =
283 rImp.GetAbsoluteReference(sValue);
284 INetURLObject::translateToInternal( rTmp, msBookmark,
285 INetURLObject::DECODE_UNAMBIGUOUS,
286 RTL_TEXTENCODING_UTF8 );
289 break;
293 if( mbValid )
294 mbValid = sEventName.getLength() != 0;
297 SdXMLEventContext::~SdXMLEventContext()
301 SvXMLImportContext * SdXMLEventContext::CreateChildContext( USHORT nPrefix, const OUString& rLocalName, const Reference< XAttributeList>& xAttrList )
303 return new XMLEventSoundContext( GetImport(), nPrefix, rLocalName, xAttrList, this );
306 void SdXMLEventContext::EndElement()
308 if( !mbValid )
309 return;
313 Reference< XEventsSupplier > xEventsSupplier( mxShape, UNO_QUERY );
314 if( !xEventsSupplier.is() )
315 break;
317 Reference< XNameReplace > xEvents( xEventsSupplier->getEvents() );
318 DBG_ASSERT( xEvents.is(), "XEventsSupplier::getEvents() returned NULL" );
319 if( !xEvents.is() )
320 break;
322 OUString sAPIEventName;
323 uno::Sequence< beans::PropertyValue > aProperties;
325 sAPIEventName = OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) );
327 if( mbScript )
328 meClickAction = ClickAction_MACRO;
330 sal_Int32 nPropertyCount = 2;
331 switch( meClickAction )
333 case ClickAction_NONE:
334 case ClickAction_PREVPAGE:
335 case ClickAction_NEXTPAGE:
336 case ClickAction_FIRSTPAGE:
337 case ClickAction_LASTPAGE:
338 case ClickAction_INVISIBLE:
339 case ClickAction_STOPPRESENTATION:
340 break;
341 case ClickAction_PROGRAM:
342 case ClickAction_VERB:
343 case ClickAction_BOOKMARK:
344 case ClickAction_DOCUMENT:
345 nPropertyCount += 1;
346 break;
347 case ClickAction_MACRO:
348 if ( msLanguage.equalsIgnoreAsciiCaseAscii("starbasic") )
349 nPropertyCount += 1;
350 break;
352 case ClickAction_SOUND:
353 nPropertyCount += 2;
354 break;
356 case ClickAction_VANISH:
357 nPropertyCount += 4;
358 break;
359 default:
360 break;
363 aProperties.realloc( nPropertyCount );
364 beans::PropertyValue* pProperties = aProperties.getArray();
366 if( ClickAction_MACRO == meClickAction )
368 if ( msLanguage.equalsIgnoreAsciiCaseAscii("starbasic") )
370 OUString sLibrary;
371 const OUString& rApp = GetXMLToken( XML_APPLICATION );
372 const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
373 if( msMacroName.getLength() > rApp.getLength()+1 &&
374 msMacroName.copy(0,rApp.getLength()).equalsIgnoreAsciiCase( rApp ) &&
375 ':' == msMacroName[rApp.getLength()] )
377 sLibrary = OUString(RTL_CONSTASCII_USTRINGPARAM("StarOffice"));
378 msMacroName = msMacroName.copy( rApp.getLength()+1 );
380 else if( msMacroName.getLength() > rDoc.getLength()+1 &&
381 msMacroName.copy(0,rDoc.getLength()).equalsIgnoreAsciiCase( rDoc ) &&
382 ':' == msMacroName[rDoc.getLength()] )
384 sLibrary = rDoc;
385 msMacroName = msMacroName.copy( rDoc.getLength()+1 );
388 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) );
389 pProperties->Handle = -1;
390 pProperties->Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM("StarBasic") );
391 pProperties->State = beans::PropertyState_DIRECT_VALUE;
392 pProperties++;
394 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "MacroName" ) );
395 pProperties->Handle = -1;
396 pProperties->Value <<= msMacroName;
397 pProperties->State = beans::PropertyState_DIRECT_VALUE;
398 pProperties++;
400 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Library" ) );
401 pProperties->Handle = -1;
402 pProperties->Value <<= sLibrary;
403 pProperties->State = beans::PropertyState_DIRECT_VALUE;
405 else
407 pProperties->Name =
408 OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) );
409 pProperties->Handle = -1;
410 pProperties->Value <<= OUString(
411 RTL_CONSTASCII_USTRINGPARAM("Script") );
412 pProperties->State = beans::PropertyState_DIRECT_VALUE;
413 pProperties++;
415 pProperties->Name = OUString(
416 RTL_CONSTASCII_USTRINGPARAM( "Script" ) );
417 pProperties->Handle = -1;
418 pProperties->Value <<= msMacroName;
419 pProperties->State = beans::PropertyState_DIRECT_VALUE;
422 else
424 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EventType" ) );
425 pProperties->Handle = -1;
426 pProperties->Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM("Presentation") );
427 pProperties->State = beans::PropertyState_DIRECT_VALUE;
428 pProperties++;
430 // ClickAction_BOOKMARK and ClickAction_DOCUMENT share the same xml event
431 // so check here if its realy a bookmark or maybe a document
432 if( meClickAction == ClickAction_BOOKMARK )
434 if( msBookmark.compareToAscii( "#", 1 ) != 0 )
435 meClickAction = ClickAction_DOCUMENT;
438 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("ClickAction") );
439 pProperties->Handle = -1;
440 pProperties->Value <<= meClickAction;
441 pProperties->State = beans::PropertyState_DIRECT_VALUE;
442 pProperties++;
444 switch( meClickAction )
446 case ClickAction_NONE:
447 case ClickAction_PREVPAGE:
448 case ClickAction_NEXTPAGE:
449 case ClickAction_FIRSTPAGE:
450 case ClickAction_LASTPAGE:
451 case ClickAction_INVISIBLE:
452 case ClickAction_STOPPRESENTATION:
453 break;
455 case ClickAction_BOOKMARK:
456 msBookmark = msBookmark.copy(1);
458 // Note: no break here!!!
460 case ClickAction_DOCUMENT:
461 case ClickAction_PROGRAM:
462 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Bookmark") );
463 pProperties->Handle = -1;
464 pProperties->Value <<= msBookmark;
465 pProperties->State = beans::PropertyState_DIRECT_VALUE;
466 break;
468 case ClickAction_VANISH:
469 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Effect") );
470 pProperties->Handle = -1;
471 pProperties->Value <<= ImplSdXMLgetEffect( meEffect, meDirection, mnStartScale, sal_True );
472 pProperties->State = beans::PropertyState_DIRECT_VALUE;
473 pProperties++;
475 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Speed") );
476 pProperties->Handle = -1;
477 pProperties->Value <<= meSpeed;
478 pProperties->State = beans::PropertyState_DIRECT_VALUE;
479 pProperties++;
481 // NOTE: no break here!!!
483 case ClickAction_SOUND:
484 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("SoundURL") );
485 pProperties->Handle = -1;
486 pProperties->Value <<= msSoundURL;
487 pProperties->State = beans::PropertyState_DIRECT_VALUE;
488 pProperties++;
490 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("PlayFull") );
491 pProperties->Handle = -1;
492 pProperties->Value = ::cppu::bool2any(mbPlayFull);
493 pProperties->State = beans::PropertyState_DIRECT_VALUE;
494 break;
496 case ClickAction_VERB:
497 pProperties->Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Verb") );
498 pProperties->Handle = -1;
499 pProperties->Value <<= mnVerb;
500 pProperties->State = beans::PropertyState_DIRECT_VALUE;
501 break;
502 case ClickAction_MACRO:
503 DBG_ERROR("xmloff::SdXMLEventContext::EndElement(), ClickAction_MACRO must be handled in different if case");
504 break;
505 default:
506 break;
509 xEvents->replaceByName( sAPIEventName, uno::Any( aProperties ) );
511 } while(0);
514 ///////////////////////////////////////////////////////////////////////
516 TYPEINIT1( SdXMLEventsContext, SvXMLImportContext );
518 SdXMLEventsContext::SdXMLEventsContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLocalName,
519 const Reference< XAttributeList>&, const Reference< XShape >& rxShape)
520 : SvXMLImportContext(rImport, nPrfx, rLocalName), mxShape( rxShape )
524 SdXMLEventsContext::~SdXMLEventsContext()
528 SvXMLImportContext * SdXMLEventsContext::CreateChildContext( USHORT nPrfx, const ::rtl::OUString& rLocalName,
529 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
531 return new SdXMLEventContext( GetImport(), nPrfx, rLocalName, xAttrList, mxShape );