merge the formfield patch from ooo-build
[ooovba.git] / xmloff / source / transform / EventOASISTContext.cxx
blob96acba4e50b4dd07e37006aa323da7811e636dde
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: EventOASISTContext.cxx,v $
10 * $Revision: 1.9 $
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"
33 #include "EventOASISTContext.hxx"
34 #include "EventMap.hxx"
35 #include "MutableAttrList.hxx"
36 #include "xmlnmspe.hxx"
37 #include "ActionMapTypesOASIS.hxx"
38 #include "AttrTransformerAction.hxx"
39 #include "TransformerActions.hxx"
40 #ifndef _XMLOFF_TRANSFORMERBASE_HXX
41 #include "TransformerBase.hxx"
42 #endif
44 #ifndef OASIS_FILTER_OOO_1X
45 // Used to parse Scripting Framework URLs
46 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
47 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
48 #include <comphelper/processfactory.hxx>
49 #endif
51 #include <hash_map>
53 using ::rtl::OUString;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::xml::sax;
57 using namespace ::xmloff::token;
59 class XMLTransformerOASISEventMap_Impl:
60 public ::std::hash_map< NameKey_Impl, ::rtl::OUString,
61 NameHash_Impl, NameHash_Impl >
63 public:
64 XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit );
65 ~XMLTransformerOASISEventMap_Impl();
68 XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit )
70 if( pInit )
72 XMLTransformerOASISEventMap_Impl::key_type aKey;
73 XMLTransformerOASISEventMap_Impl::data_type aData;
74 while( pInit->m_pOASISName )
76 aKey.m_nPrefix = pInit->m_nOASISPrefix;
77 aKey.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName);
79 OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" );
81 aData = OUString::createFromAscii(pInit->m_pOOoName);
83 XMLTransformerOASISEventMap_Impl::value_type aVal( aKey, aData );
85 insert( aVal );
86 ++pInit;
91 XMLTransformerOASISEventMap_Impl::~XMLTransformerOASISEventMap_Impl()
95 // -----------------------------------------------------------------------------
97 TYPEINIT1( XMLEventOASISTransformerContext, XMLRenameElemTransformerContext);
99 XMLEventOASISTransformerContext::XMLEventOASISTransformerContext(
100 XMLTransformerBase& rImp,
101 const OUString& rQName ) :
102 XMLRenameElemTransformerContext( rImp, rQName,
103 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT )
107 XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext()
111 XMLTransformerOASISEventMap_Impl
112 *XMLEventOASISTransformerContext::CreateEventMap()
114 return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap );
117 XMLTransformerOASISEventMap_Impl
118 *XMLEventOASISTransformerContext::CreateFormEventMap()
120 return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap );
123 void XMLEventOASISTransformerContext::FlushEventMap(
124 XMLTransformerOASISEventMap_Impl *p )
126 delete p;
129 OUString XMLEventOASISTransformerContext::GetEventName(
130 sal_uInt16 nPrefix,
131 const OUString& rName,
132 XMLTransformerOASISEventMap_Impl& rMap,
133 XMLTransformerOASISEventMap_Impl *pMap2)
135 XMLTransformerOASISEventMap_Impl::key_type aKey( nPrefix, rName );
136 if( pMap2 )
138 XMLTransformerOASISEventMap_Impl::const_iterator aIter =
139 pMap2->find( aKey );
140 if( !(aIter == pMap2->end()) )
141 return (*aIter).second;
144 XMLTransformerOASISEventMap_Impl::const_iterator aIter = rMap.find( aKey );
145 if( aIter == rMap.end() )
146 return rName;
147 else
148 return (*aIter).second;
151 bool ParseURLAsString(
152 const OUString& rAttrValue,
153 OUString* pName, OUString* pLocation )
155 OUString SCHEME( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:" ) );
157 sal_Int32 params = rAttrValue.indexOf( '?' );
158 if ( rAttrValue.indexOf( SCHEME ) != 0 || params < 0 )
160 return FALSE;
163 sal_Int32 start = SCHEME.getLength();
164 *pName = rAttrValue.copy( start, params - start );
166 OUString aToken;
167 OUString aLanguage;
168 params++;
171 aToken = rAttrValue.getToken( 0, '&', params );
172 sal_Int32 dummy = 0;
174 if ( aToken.match( GetXMLToken( XML_LANGUAGE ) ) )
176 aLanguage = aToken.getToken( 1, '=', dummy );
178 else if ( aToken.match( GetXMLToken( XML_LOCATION ) ) )
180 OUString tmp = aToken.getToken( 1, '=', dummy );
181 if ( tmp.equalsIgnoreAsciiCase( GetXMLToken( XML_DOCUMENT ) ) )
183 *pLocation = GetXMLToken( XML_DOCUMENT );
185 else
187 *pLocation = GetXMLToken( XML_APPLICATION );
190 } while ( params >= 0 );
192 if ( aLanguage.equalsIgnoreAsciiCaseAscii( "basic" ) )
194 return TRUE;
196 return FALSE;
199 bool ParseURL(
200 const OUString& rAttrValue,
201 OUString* pName, OUString* pLocation )
203 #ifdef OASIS_FILTER_OOO_1X
204 return ParseURLAsString( rAttrValue, pName, pLocation );
205 #else
206 Reference< com::sun::star::lang::XMultiServiceFactory >
207 xSMgr = ::comphelper::getProcessServiceFactory();
209 Reference< com::sun::star::uri::XUriReferenceFactory >
210 xFactory( xSMgr->createInstance( OUString::createFromAscii(
211 "com.sun.star.uri.UriReferenceFactory" ) ), UNO_QUERY );
213 if ( xFactory.is() )
215 Reference< com::sun::star::uri::XVndSunStarScriptUrl > xUrl (
216 xFactory->parse( rAttrValue ), UNO_QUERY );
218 if ( xUrl.is() )
220 OUString aLanguageKey = GetXMLToken( XML_LANGUAGE );
221 if ( xUrl.is() && xUrl->hasParameter( aLanguageKey ) )
223 OUString aLanguage = xUrl->getParameter( aLanguageKey );
225 if ( aLanguage.equalsIgnoreAsciiCaseAscii( "basic" ) )
227 *pName = xUrl->getName();
229 OUString tmp =
230 xUrl->getParameter( GetXMLToken( XML_LOCATION ) );
232 OUString doc = GetXMLToken( XML_DOCUMENT );
234 if ( tmp.equalsIgnoreAsciiCase( doc ) )
236 *pLocation = doc;
238 else
240 *pLocation = GetXMLToken( XML_APPLICATION );
242 return TRUE;
246 return FALSE;
248 else
250 return ParseURLAsString( rAttrValue, pName, pLocation );
252 #endif
255 void XMLEventOASISTransformerContext::StartElement(
256 const Reference< XAttributeList >& rAttrList )
258 OSL_TRACE("XMLEventOASISTransformerContext::StartElement");
260 XMLTransformerActions *pActions =
261 GetTransformer().GetUserDefinedActions( OASIS_EVENT_ACTIONS );
262 OSL_ENSURE( pActions, "go no actions" );
264 Reference< XAttributeList > xAttrList( rAttrList );
265 XMLMutableAttributeList *pMutableAttrList = 0;
266 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
267 for( sal_Int16 i=0; i < nAttrCount; i++ )
269 const OUString& rAttrName = xAttrList->getNameByIndex( i );
270 OUString aLocalName;
271 sal_uInt16 nPrefix =
272 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
273 &aLocalName );
274 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
275 XMLTransformerActions::const_iterator aIter =
276 pActions->find( aKey );
277 if( !(aIter == pActions->end() ) )
279 if( !pMutableAttrList )
281 pMutableAttrList =
282 new XMLMutableAttributeList( xAttrList );
283 xAttrList = pMutableAttrList;
285 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
286 switch( (*aIter).second.m_nActionType )
288 case XML_ATACTION_HREF:
290 OUString aAttrValue( rAttrValue );
291 OUString aName, aLocation;
293 bool bNeedsTransform =
294 ParseURL( rAttrValue, &aName, &aLocation );
296 if ( bNeedsTransform )
298 pMutableAttrList->RemoveAttributeByIndex( i );
300 OUString aAttrQName(
301 GetTransformer().GetNamespaceMap().GetQNameByKey(
302 XML_NAMESPACE_SCRIPT,
303 ::xmloff::token::GetXMLToken( XML_MACRO_NAME ) ) );
305 pMutableAttrList->AddAttribute( aAttrQName, aName );
307 sal_Int16 idx = pMutableAttrList->GetIndexByName(
308 GetTransformer().GetNamespaceMap().GetQNameByKey(
309 XML_NAMESPACE_SCRIPT,
310 GetXMLToken( XML_LANGUAGE ) ) );
312 pMutableAttrList->SetValueByIndex( idx,
313 OUString::createFromAscii("StarBasic") );
315 OUString aLocQName(
316 GetTransformer().GetNamespaceMap().GetQNameByKey(
317 XML_NAMESPACE_SCRIPT,
318 GetXMLToken( XML_LOCATION ) ) );
320 pMutableAttrList->AddAttribute( aLocQName, aLocation );
323 break;
324 case XML_ATACTION_EVENT_NAME:
326 // Check if the event belongs to a form or control by
327 // cehcking the 2nd ancestor element, f.i.:
328 // <form:button><form:event-listeners><form:event-listener>
329 const XMLTransformerContext *pObjContext =
330 GetTransformer().GetAncestorContext( 1 );
331 sal_Bool bForm = pObjContext &&
333 pObjContext->HasNamespace(XML_NAMESPACE_FORM );
334 pMutableAttrList->SetValueByIndex( i,
335 GetTransformer().GetEventName( rAttrValue,
336 bForm ) );
338 break;
339 case XML_ATACTION_REMOVE_NAMESPACE_PREFIX:
341 OUString aAttrValue( rAttrValue );
342 sal_uInt16 nValPrefix =
343 static_cast<sal_uInt16>((*aIter).second.m_nParam1);
344 if( GetTransformer().RemoveNamespacePrefix(
345 aAttrValue, nValPrefix ) )
346 pMutableAttrList->SetValueByIndex( i, aAttrValue );
348 break;
349 case XML_ATACTION_MACRO_NAME:
351 OUString aName, aLocation;
352 bool bNeedsTransform =
353 ParseURL( rAttrValue, &aName, &aLocation );
355 if ( bNeedsTransform )
357 pMutableAttrList->SetValueByIndex( i, aName );
359 sal_Int16 idx = pMutableAttrList->GetIndexByName(
360 GetTransformer().GetNamespaceMap().GetQNameByKey(
361 XML_NAMESPACE_SCRIPT,
362 GetXMLToken( XML_LANGUAGE ) ) );
364 pMutableAttrList->SetValueByIndex( idx,
365 OUString::createFromAscii("StarBasic") );
367 OUString aLocQName(
368 GetTransformer().GetNamespaceMap().GetQNameByKey(
369 XML_NAMESPACE_SCRIPT,
370 GetXMLToken( XML_LOCATION ) ) );
372 pMutableAttrList->AddAttribute( aLocQName, aLocation );
374 else
376 const OUString& rApp = GetXMLToken( XML_APPLICATION );
377 const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
378 OUString aAttrValue;
379 if( rAttrValue.getLength() > rApp.getLength()+1 &&
380 rAttrValue.copy(0,rApp.getLength()).
381 equalsIgnoreAsciiCase( rApp ) &&
382 ':' == rAttrValue[rApp.getLength()] )
384 aLocation = rApp;
385 aAttrValue = rAttrValue.copy( rApp.getLength()+1 );
387 else if( rAttrValue.getLength() > rDoc.getLength()+1 &&
388 rAttrValue.copy(0,rDoc.getLength()).
389 equalsIgnoreAsciiCase( rDoc ) &&
390 ':' == rAttrValue[rDoc.getLength()] )
392 aLocation= rDoc;
393 aAttrValue = rAttrValue.copy( rDoc.getLength()+1 );
395 if( aAttrValue.getLength() )
396 pMutableAttrList->SetValueByIndex( i,
397 aAttrValue );
398 if( aLocation.getLength() )
400 OUString aAttrQName( GetTransformer().GetNamespaceMap().
401 GetQNameByKey( XML_NAMESPACE_SCRIPT,
402 ::xmloff::token::GetXMLToken( XML_LOCATION ) ) );
403 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
404 // draw bug
405 aAttrQName = GetTransformer().GetNamespaceMap().
406 GetQNameByKey( XML_NAMESPACE_SCRIPT,
407 ::xmloff::token::GetXMLToken( XML_LIBRARY ) );
408 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
412 break;
413 case XML_ATACTION_COPY:
414 break;
415 default:
416 OSL_ENSURE( !this, "unknown action" );
417 break;
422 XMLRenameElemTransformerContext::StartElement( xAttrList );