Update git submodules
[LibreOffice.git] / xmloff / source / transform / EventOASISTContext.cxx
blob5a1111f93909f4bdb16f788a84b292efba0df2cd
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/xmlnamespace.hxx>
24 #include "ActionMapTypesOASIS.hxx"
25 #include "AttrTransformerAction.hxx"
26 #include "TransformerActions.hxx"
27 #include "TransformerBase.hxx"
28 #include <osl/diagnose.h>
29 #include <sal/log.hxx>
30 #include <o3tl/string_view.hxx>
32 // Used to parse Scripting Framework URLs
33 #include <com/sun/star/uri/UriReferenceFactory.hpp>
34 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
35 #include <comphelper/processfactory.hxx>
37 #include <unordered_map>
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::xml::sax;
41 using namespace ::xmloff::token;
43 class XMLTransformerOASISEventMap_Impl:
44 public std::unordered_map< NameKey_Impl, OUString,
45 NameHash_Impl, NameHash_Impl >
47 public:
48 explicit XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry const *pInit );
51 XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry const *pInit )
53 if( !pInit )
54 return;
56 XMLTransformerOASISEventMap_Impl::key_type aKey;
57 XMLTransformerOASISEventMap_Impl::mapped_type aData;
58 while( !pInit->m_pOASISName.isEmpty() )
60 aKey.m_nPrefix = pInit->m_nOASISPrefix;
61 aKey.m_aLocalName = pInit->m_pOASISName;
63 OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" );
65 aData = pInit->m_pOOoName;
67 XMLTransformerOASISEventMap_Impl::value_type aVal( aKey, aData );
69 insert( aVal );
70 ++pInit;
74 XMLEventOASISTransformerContext::XMLEventOASISTransformerContext(
75 XMLTransformerBase& rImp,
76 const OUString& rQName ) :
77 XMLRenameElemTransformerContext( rImp, rQName,
78 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT )
82 XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext()
86 XMLTransformerOASISEventMap_Impl
87 *XMLEventOASISTransformerContext::CreateEventMap()
89 return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap );
92 XMLTransformerOASISEventMap_Impl
93 *XMLEventOASISTransformerContext::CreateFormEventMap()
95 return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap );
98 void XMLEventOASISTransformerContext::FlushEventMap(
99 XMLTransformerOASISEventMap_Impl *p )
101 delete p;
104 OUString XMLEventOASISTransformerContext::GetEventName(
105 sal_uInt16 nPrefix,
106 const OUString& rName,
107 XMLTransformerOASISEventMap_Impl& rMap,
108 XMLTransformerOASISEventMap_Impl *pMap2)
110 XMLTransformerOASISEventMap_Impl::key_type aKey( nPrefix, rName );
111 if( pMap2 )
113 XMLTransformerOASISEventMap_Impl::const_iterator aIter =
114 pMap2->find( aKey );
115 if( aIter != pMap2->end() )
116 return (*aIter).second;
119 XMLTransformerOASISEventMap_Impl::const_iterator aIter = rMap.find( aKey );
120 if( aIter == rMap.end() )
121 return rName;
122 else
123 return (*aIter).second;
126 static bool ParseURL(
127 const OUString& rAttrValue,
128 OUString* pName, OUString* pLocation )
130 const Reference< css::uno::XComponentContext >& xContext = ::comphelper::getProcessComponentContext();
132 Reference< css::uri::XUriReferenceFactory > xFactory = css::uri::UriReferenceFactory::create(xContext);
134 Reference< css::uri::XVndSunStarScriptUrl > xUrl ( xFactory->parse( rAttrValue ), UNO_QUERY );
136 if ( xUrl.is() )
138 const OUString& aLanguageKey = GetXMLToken( XML_LANGUAGE );
139 if ( xUrl.is() && xUrl->hasParameter( aLanguageKey ) )
141 OUString aLanguage = xUrl->getParameter( aLanguageKey );
143 if ( aLanguage.equalsIgnoreAsciiCase("basic") )
145 *pName = xUrl->getName();
147 OUString tmp =
148 xUrl->getParameter( GetXMLToken( XML_LOCATION ) );
150 const OUString& doc = GetXMLToken( XML_DOCUMENT );
152 if ( tmp.equalsIgnoreAsciiCase( doc ) )
154 *pLocation = doc;
156 else
158 *pLocation = GetXMLToken( XML_APPLICATION );
160 return true;
164 return false;
167 void XMLEventOASISTransformerContext::StartElement(
168 const Reference< XAttributeList >& rAttrList )
170 SAL_INFO("xmloff.transform", "XMLEventOASISTransformerContext::StartElement");
172 XMLTransformerActions *pActions =
173 GetTransformer().GetUserDefinedActions( OASIS_EVENT_ACTIONS );
174 SAL_WARN_IF( pActions == nullptr, "xmloff.transform", "got no actions" );
176 Reference< XAttributeList > xAttrList( rAttrList );
177 rtl::Reference<XMLMutableAttributeList> pMutableAttrList;
178 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
179 for( sal_Int16 i=0; i < nAttrCount; i++ )
181 const OUString aAttrName = xAttrList->getNameByIndex( i );
182 OUString aLocalName;
183 sal_uInt16 nPrefix =
184 GetTransformer().GetNamespaceMap().GetKeyByAttrName( aAttrName,
185 &aLocalName );
186 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
187 XMLTransformerActions::const_iterator aIter =
188 pActions->find( aKey );
189 if( aIter != pActions->end() )
191 if( !pMutableAttrList )
193 pMutableAttrList =
194 new XMLMutableAttributeList( xAttrList );
195 xAttrList = pMutableAttrList;
197 const OUString aAttrValue = xAttrList->getValueByIndex( i );
198 switch( (*aIter).second.m_nActionType )
200 case XML_ATACTION_HREF:
202 OUString aName, aLocation;
204 bool bNeedsTransform =
205 ParseURL( aAttrValue, &aName, &aLocation );
207 if ( bNeedsTransform )
209 pMutableAttrList->RemoveAttributeByIndex( i );
211 OUString aAttrQName(
212 GetTransformer().GetNamespaceMap().GetQNameByKey(
213 XML_NAMESPACE_SCRIPT,
214 ::xmloff::token::GetXMLToken( XML_MACRO_NAME ) ) );
216 pMutableAttrList->AddAttribute( aAttrQName, aName );
218 sal_Int16 idx = pMutableAttrList->GetIndexByName(
219 GetTransformer().GetNamespaceMap().GetQNameByKey(
220 XML_NAMESPACE_SCRIPT,
221 GetXMLToken( XML_LANGUAGE ) ) );
223 if (idx != -1)
224 pMutableAttrList->SetValueByIndex(idx, u"StarBasic"_ustr);
226 OUString aLocQName(
227 GetTransformer().GetNamespaceMap().GetQNameByKey(
228 XML_NAMESPACE_SCRIPT,
229 GetXMLToken( XML_LOCATION ) ) );
231 pMutableAttrList->AddAttribute( aLocQName, aLocation );
234 break;
235 case XML_ATACTION_EVENT_NAME:
237 // Check if the event belongs to a form or control by
238 // checking the 2nd ancestor element, f.i.:
239 // <form:button><form:event-listeners><form:event-listener>
240 const XMLTransformerContext *pObjContext =
241 GetTransformer().GetAncestorContext( 1 );
242 bool bForm = pObjContext &&
244 pObjContext->HasNamespace(XML_NAMESPACE_FORM );
245 pMutableAttrList->SetValueByIndex( i,
246 GetTransformer().GetEventName( aAttrValue,
247 bForm ) );
249 break;
250 case XML_ATACTION_REMOVE_NAMESPACE_PREFIX:
252 OUString aAttrValue2( aAttrValue );
253 sal_uInt16 nValPrefix =
254 static_cast<sal_uInt16>((*aIter).second.m_nParam1);
255 if( GetTransformer().RemoveNamespacePrefix(
256 aAttrValue2, nValPrefix ) )
257 pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
259 break;
260 case XML_ATACTION_MACRO_NAME:
262 OUString aName, aLocation;
263 bool bNeedsTransform =
264 ParseURL( aAttrValue, &aName, &aLocation );
266 if ( bNeedsTransform )
268 pMutableAttrList->SetValueByIndex( i, aName );
270 sal_Int16 idx = pMutableAttrList->GetIndexByName(
271 GetTransformer().GetNamespaceMap().GetQNameByKey(
272 XML_NAMESPACE_SCRIPT,
273 GetXMLToken( XML_LANGUAGE ) ) );
275 if (idx != -1)
276 pMutableAttrList->SetValueByIndex(idx, u"StarBasic"_ustr);
278 OUString aLocQName(
279 GetTransformer().GetNamespaceMap().GetQNameByKey(
280 XML_NAMESPACE_SCRIPT,
281 GetXMLToken( XML_LOCATION ) ) );
283 pMutableAttrList->AddAttribute( aLocQName, aLocation );
285 else
287 const OUString& rApp = GetXMLToken( XML_APPLICATION );
288 const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
289 OUString aAttrValue2;
290 if( aAttrValue.getLength() > rApp.getLength()+1 &&
291 o3tl::equalsIgnoreAsciiCase(aAttrValue.subView(0,rApp.getLength()), rApp) &&
292 ':' == aAttrValue[rApp.getLength()] )
294 aLocation = rApp;
295 aAttrValue2 = aAttrValue.copy( rApp.getLength()+1 );
297 else if( aAttrValue.getLength() > rDoc.getLength()+1 &&
298 o3tl::equalsIgnoreAsciiCase(aAttrValue.subView(0,rDoc.getLength()), rDoc) &&
299 ':' == aAttrValue[rDoc.getLength()] )
301 aLocation= rDoc;
302 aAttrValue2 = aAttrValue.copy( rDoc.getLength()+1 );
304 if( !aAttrValue2.isEmpty() )
305 pMutableAttrList->SetValueByIndex( i, aAttrValue2 );
306 if( !aLocation.isEmpty() )
308 OUString aAttrQName( GetTransformer().GetNamespaceMap().
309 GetQNameByKey( XML_NAMESPACE_SCRIPT,
310 ::xmloff::token::GetXMLToken( XML_LOCATION ) ) );
311 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
312 // draw bug
313 aAttrQName = GetTransformer().GetNamespaceMap().
314 GetQNameByKey( XML_NAMESPACE_SCRIPT,
315 ::xmloff::token::GetXMLToken( XML_LIBRARY ) );
316 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
320 break;
321 case XML_ATACTION_COPY:
322 break;
323 default:
324 SAL_WARN( "xmloff.transform", "unknown action" );
325 break;
330 XMLRenameElemTransformerContext::StartElement( xAttrList );
333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */