bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / transform / EventOASISTContext.cxx
blob03213bebbcd77a173005d3b596149b76f64294b4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "EventOASISTContext.hxx"
21 #include "EventMap.hxx"
22 #include "MutableAttrList.hxx"
23 #include <xmloff/xmlnmspe.hxx>
24 #include "ActionMapTypesOASIS.hxx"
25 #include "AttrTransformerAction.hxx"
26 #include "TransformerActions.hxx"
27 #include "TransformerBase.hxx"
28 #include <osl/diagnose.h>
30 // Used to parse Scripting Framework URLs
31 #include <com/sun/star/uri/UriReferenceFactory.hpp>
32 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
33 #include <comphelper/processfactory.hxx>
35 #include <unordered_map>
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::xml::sax;
39 using namespace ::xmloff::token;
41 class XMLTransformerOASISEventMap_Impl:
42 public std::unordered_map< NameKey_Impl, OUString,
43 NameHash_Impl, NameHash_Impl >
45 public:
46 XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit );
47 ~XMLTransformerOASISEventMap_Impl();
50 XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit )
52 if( pInit )
54 XMLTransformerOASISEventMap_Impl::key_type aKey;
55 XMLTransformerOASISEventMap_Impl::mapped_type aData;
56 while( pInit->m_pOASISName )
58 aKey.m_nPrefix = pInit->m_nOASISPrefix;
59 aKey.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName);
61 OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" );
63 aData = OUString::createFromAscii(pInit->m_pOOoName);
65 XMLTransformerOASISEventMap_Impl::value_type aVal( aKey, aData );
67 insert( aVal );
68 ++pInit;
73 XMLTransformerOASISEventMap_Impl::~XMLTransformerOASISEventMap_Impl()
77 TYPEINIT1( XMLEventOASISTransformerContext, XMLRenameElemTransformerContext);
79 XMLEventOASISTransformerContext::XMLEventOASISTransformerContext(
80 XMLTransformerBase& rImp,
81 const OUString& rQName ) :
82 XMLRenameElemTransformerContext( rImp, rQName,
83 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT )
87 XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext()
91 XMLTransformerOASISEventMap_Impl
92 *XMLEventOASISTransformerContext::CreateEventMap()
94 return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap );
97 XMLTransformerOASISEventMap_Impl
98 *XMLEventOASISTransformerContext::CreateFormEventMap()
100 return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap );
103 void XMLEventOASISTransformerContext::FlushEventMap(
104 XMLTransformerOASISEventMap_Impl *p )
106 delete p;
109 OUString XMLEventOASISTransformerContext::GetEventName(
110 sal_uInt16 nPrefix,
111 const OUString& rName,
112 XMLTransformerOASISEventMap_Impl& rMap,
113 XMLTransformerOASISEventMap_Impl *pMap2)
115 XMLTransformerOASISEventMap_Impl::key_type aKey( nPrefix, rName );
116 if( pMap2 )
118 XMLTransformerOASISEventMap_Impl::const_iterator aIter =
119 pMap2->find( aKey );
120 if( !(aIter == pMap2->end()) )
121 return (*aIter).second;
124 XMLTransformerOASISEventMap_Impl::const_iterator aIter = rMap.find( aKey );
125 if( aIter == rMap.end() )
126 return rName;
127 else
128 return (*aIter).second;
131 bool ParseURL(
132 const OUString& rAttrValue,
133 OUString* pName, OUString* pLocation )
135 Reference< com::sun::star::uno::XComponentContext >
136 xContext = ::comphelper::getProcessComponentContext();
138 Reference< com::sun::star::uri::XUriReferenceFactory > xFactory =
139 com::sun::star::uri::UriReferenceFactory::create(xContext);
141 Reference< com::sun::star::uri::XVndSunStarScriptUrl > xUrl (
142 xFactory->parse( rAttrValue ), UNO_QUERY );
144 if ( xUrl.is() )
146 OUString aLanguageKey = GetXMLToken( XML_LANGUAGE );
147 if ( xUrl.is() && xUrl->hasParameter( aLanguageKey ) )
149 OUString aLanguage = xUrl->getParameter( aLanguageKey );
151 if ( aLanguage.equalsIgnoreAsciiCase("basic") )
153 *pName = xUrl->getName();
155 OUString tmp =
156 xUrl->getParameter( GetXMLToken( XML_LOCATION ) );
158 OUString doc = GetXMLToken( XML_DOCUMENT );
160 if ( tmp.equalsIgnoreAsciiCase( doc ) )
162 *pLocation = doc;
164 else
166 *pLocation = GetXMLToken( XML_APPLICATION );
168 return true;
172 return false;
175 void XMLEventOASISTransformerContext::StartElement(
176 const Reference< XAttributeList >& rAttrList )
178 SAL_INFO("xmloff.transform", "XMLEventOASISTransformerContext::StartElement");
180 XMLTransformerActions *pActions =
181 GetTransformer().GetUserDefinedActions( OASIS_EVENT_ACTIONS );
182 SAL_WARN_IF( pActions == NULL, "xmloff.transform", "got no actions" );
184 Reference< XAttributeList > xAttrList( rAttrList );
185 XMLMutableAttributeList *pMutableAttrList = 0;
186 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
187 for( sal_Int16 i=0; i < nAttrCount; i++ )
189 const OUString& rAttrName = xAttrList->getNameByIndex( i );
190 OUString aLocalName;
191 sal_uInt16 nPrefix =
192 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
193 &aLocalName );
194 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
195 XMLTransformerActions::const_iterator aIter =
196 pActions->find( aKey );
197 if( !(aIter == pActions->end() ) )
199 if( !pMutableAttrList )
201 pMutableAttrList =
202 new XMLMutableAttributeList( xAttrList );
203 xAttrList = pMutableAttrList;
205 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
206 switch( (*aIter).second.m_nActionType )
208 case XML_ATACTION_HREF:
210 OUString aName, aLocation;
212 bool bNeedsTransform =
213 ParseURL( rAttrValue, &aName, &aLocation );
215 if ( bNeedsTransform )
217 pMutableAttrList->RemoveAttributeByIndex( i );
219 OUString aAttrQName(
220 GetTransformer().GetNamespaceMap().GetQNameByKey(
221 XML_NAMESPACE_SCRIPT,
222 ::xmloff::token::GetXMLToken( XML_MACRO_NAME ) ) );
224 pMutableAttrList->AddAttribute( aAttrQName, aName );
226 sal_Int16 idx = pMutableAttrList->GetIndexByName(
227 GetTransformer().GetNamespaceMap().GetQNameByKey(
228 XML_NAMESPACE_SCRIPT,
229 GetXMLToken( XML_LANGUAGE ) ) );
231 pMutableAttrList->SetValueByIndex( idx,
232 OUString("StarBasic") );
234 OUString aLocQName(
235 GetTransformer().GetNamespaceMap().GetQNameByKey(
236 XML_NAMESPACE_SCRIPT,
237 GetXMLToken( XML_LOCATION ) ) );
239 pMutableAttrList->AddAttribute( aLocQName, aLocation );
242 break;
243 case XML_ATACTION_EVENT_NAME:
245 // Check if the event belongs to a form or control by
246 // cehcking the 2nd ancestor element, f.i.:
247 // <form:button><form:event-listeners><form:event-listener>
248 const XMLTransformerContext *pObjContext =
249 GetTransformer().GetAncestorContext( 1 );
250 bool bForm = pObjContext &&
252 pObjContext->HasNamespace(XML_NAMESPACE_FORM );
253 pMutableAttrList->SetValueByIndex( i,
254 GetTransformer().GetEventName( rAttrValue,
255 bForm ) );
257 break;
258 case XML_ATACTION_REMOVE_NAMESPACE_PREFIX:
260 OUString aAttrValue( rAttrValue );
261 sal_uInt16 nValPrefix =
262 static_cast<sal_uInt16>((*aIter).second.m_nParam1);
263 if( GetTransformer().RemoveNamespacePrefix(
264 aAttrValue, nValPrefix ) )
265 pMutableAttrList->SetValueByIndex( i, aAttrValue );
267 break;
268 case XML_ATACTION_MACRO_NAME:
270 OUString aName, aLocation;
271 bool bNeedsTransform =
272 ParseURL( rAttrValue, &aName, &aLocation );
274 if ( bNeedsTransform )
276 pMutableAttrList->SetValueByIndex( i, aName );
278 sal_Int16 idx = pMutableAttrList->GetIndexByName(
279 GetTransformer().GetNamespaceMap().GetQNameByKey(
280 XML_NAMESPACE_SCRIPT,
281 GetXMLToken( XML_LANGUAGE ) ) );
283 pMutableAttrList->SetValueByIndex( idx,
284 OUString("StarBasic") );
286 OUString aLocQName(
287 GetTransformer().GetNamespaceMap().GetQNameByKey(
288 XML_NAMESPACE_SCRIPT,
289 GetXMLToken( XML_LOCATION ) ) );
291 pMutableAttrList->AddAttribute( aLocQName, aLocation );
293 else
295 const OUString& rApp = GetXMLToken( XML_APPLICATION );
296 const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
297 OUString aAttrValue;
298 if( rAttrValue.getLength() > rApp.getLength()+1 &&
299 rAttrValue.copy(0,rApp.getLength()).
300 equalsIgnoreAsciiCase( rApp ) &&
301 ':' == rAttrValue[rApp.getLength()] )
303 aLocation = rApp;
304 aAttrValue = rAttrValue.copy( rApp.getLength()+1 );
306 else if( rAttrValue.getLength() > rDoc.getLength()+1 &&
307 rAttrValue.copy(0,rDoc.getLength()).
308 equalsIgnoreAsciiCase( rDoc ) &&
309 ':' == rAttrValue[rDoc.getLength()] )
311 aLocation= rDoc;
312 aAttrValue = rAttrValue.copy( rDoc.getLength()+1 );
314 if( !aAttrValue.isEmpty() )
315 pMutableAttrList->SetValueByIndex( i,
316 aAttrValue );
317 if( !aLocation.isEmpty() )
319 OUString aAttrQName( GetTransformer().GetNamespaceMap().
320 GetQNameByKey( XML_NAMESPACE_SCRIPT,
321 ::xmloff::token::GetXMLToken( XML_LOCATION ) ) );
322 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
323 // draw bug
324 aAttrQName = GetTransformer().GetNamespaceMap().
325 GetQNameByKey( XML_NAMESPACE_SCRIPT,
326 ::xmloff::token::GetXMLToken( XML_LIBRARY ) );
327 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
331 break;
332 case XML_ATACTION_COPY:
333 break;
334 default:
335 SAL_WARN( "xmloff.transform", "unknown action" );
336 break;
341 XMLRenameElemTransformerContext::StartElement( xAttrList );
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */