1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventimp.cxx,v $
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"
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
94 com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> mxShape
;
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();
107 ClickAction meClickAction
;
109 XMLEffectDirection meDirection
;
110 sal_Int16 mnStartScale
;
111 AnimationSpeed meSpeed
;
115 OUString msMacroName
;
120 ///////////////////////////////////////////////////////////////////////
122 class XMLEventSoundContext
: public SvXMLImportContext
124 SdXMLEventContext
* mpParent
;
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
);
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
) )
186 else if( nPrfx
== XML_NAMESPACE_SCRIPT
&& IsXMLToken( rLocalName
, XML_EVENT_LISTENER
) )
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
) )
212 if( SvXMLUnitConverter::convertEnum( eEnum
, sValue
, aXML_EventActions_EnumMap
) )
213 meClickAction
= (ClickAction
)eEnum
;
215 if( IsXMLToken( aAttrLocalName
, XML_EFFECT
) )
218 if( SvXMLUnitConverter::convertEnum( eEnum
, sValue
, aXML_AnimationEffect_EnumMap
) )
219 meEffect
= (XMLEffect
)eEnum
;
221 else if( IsXMLToken( aAttrLocalName
, XML_DIRECTION
) )
224 if( SvXMLUnitConverter::convertEnum( eEnum
, sValue
, aXML_AnimationDirection_EnumMap
) )
225 meDirection
= (XMLEffectDirection
)eEnum
;
227 else if( IsXMLToken( aAttrLocalName
, XML_START_SCALE
) )
230 if( SvXMLUnitConverter::convertPercent( nScale
, sValue
) )
231 mnStartScale
= (sal_Int16
)nScale
;
233 else if( IsXMLToken( aAttrLocalName
, XML_SPEED
) )
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
);
245 case XML_NAMESPACE_SCRIPT
:
246 if( IsXMLToken( aAttrLocalName
, XML_EVENT_NAME
) )
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
;
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 ) )
269 // msLibrary = sValue;
273 case XML_NAMESPACE_XLINK
:
274 if( IsXMLToken( aAttrLocalName
, XML_HREF
) )
278 msMacroName
= sValue
;
282 const rtl::OUString
&rTmp
=
283 rImp
.GetAbsoluteReference(sValue
);
284 INetURLObject::translateToInternal( rTmp
, msBookmark
,
285 INetURLObject::DECODE_UNAMBIGUOUS
,
286 RTL_TEXTENCODING_UTF8
);
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()
313 Reference
< XEventsSupplier
> xEventsSupplier( mxShape
, UNO_QUERY
);
314 if( !xEventsSupplier
.is() )
317 Reference
< XNameReplace
> xEvents( xEventsSupplier
->getEvents() );
318 DBG_ASSERT( xEvents
.is(), "XEventsSupplier::getEvents() returned NULL" );
322 OUString sAPIEventName
;
323 uno::Sequence
< beans::PropertyValue
> aProperties
;
325 sAPIEventName
= OUString( RTL_CONSTASCII_USTRINGPARAM( "OnClick" ) );
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
:
341 case ClickAction_PROGRAM
:
342 case ClickAction_VERB
:
343 case ClickAction_BOOKMARK
:
344 case ClickAction_DOCUMENT
:
347 case ClickAction_MACRO
:
348 if ( msLanguage
.equalsIgnoreAsciiCaseAscii("starbasic") )
352 case ClickAction_SOUND
:
356 case ClickAction_VANISH
:
363 aProperties
.realloc( nPropertyCount
);
364 beans::PropertyValue
* pProperties
= aProperties
.getArray();
366 if( ClickAction_MACRO
== meClickAction
)
368 if ( msLanguage
.equalsIgnoreAsciiCaseAscii("starbasic") )
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()] )
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
;
394 pProperties
->Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "MacroName" ) );
395 pProperties
->Handle
= -1;
396 pProperties
->Value
<<= msMacroName
;
397 pProperties
->State
= beans::PropertyState_DIRECT_VALUE
;
400 pProperties
->Name
= OUString( RTL_CONSTASCII_USTRINGPARAM( "Library" ) );
401 pProperties
->Handle
= -1;
402 pProperties
->Value
<<= sLibrary
;
403 pProperties
->State
= beans::PropertyState_DIRECT_VALUE
;
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
;
415 pProperties
->Name
= OUString(
416 RTL_CONSTASCII_USTRINGPARAM( "Script" ) );
417 pProperties
->Handle
= -1;
418 pProperties
->Value
<<= msMacroName
;
419 pProperties
->State
= beans::PropertyState_DIRECT_VALUE
;
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
;
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
;
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
:
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
;
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
;
475 pProperties
->Name
= OUString( RTL_CONSTASCII_USTRINGPARAM("Speed") );
476 pProperties
->Handle
= -1;
477 pProperties
->Value
<<= meSpeed
;
478 pProperties
->State
= beans::PropertyState_DIRECT_VALUE
;
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
;
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
;
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
;
502 case ClickAction_MACRO
:
503 DBG_ERROR("xmloff::SdXMLEventContext::EndElement(), ClickAction_MACRO must be handled in different if case");
509 xEvents
->replaceByName( sAPIEventName
, uno::Any( aProperties
) );
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
);