bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / script / XMLEventExport.cxx
bloba27927c082afca0bf8c4389c10ea1c47b2ee00ec
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 <xmloff/XMLEventExport.hxx>
22 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <com/sun/star/document/XEventsSupplier.hpp>
26 #include <com/sun/star/container/XNameReplace.hpp>
27 #include <tools/debug.hxx>
28 #include <xmloff/xmlexp.hxx>
29 #include <xmloff/xmltoken.hxx>
30 #include <xmloff/xmlnmspe.hxx>
31 #include <xmloff/nmspmap.hxx>
34 using namespace ::com::sun::star::uno;
36 using std::map;
37 using ::com::sun::star::beans::PropertyValue;
38 using ::com::sun::star::document::XEventsSupplier;
39 using ::com::sun::star::container::XNameReplace;
40 using ::com::sun::star::container::XNameAccess;
41 using ::xmloff::token::GetXMLToken;
42 using ::xmloff::token::XML_EVENT_LISTENERS;
45 XMLEventExport::XMLEventExport(SvXMLExport& rExp,
46 const XMLEventNameTranslation* pTranslationTable) :
47 sEventType("EventType"),
48 rExport(rExp),
49 bExtNamespace(false)
51 AddTranslationTable(pTranslationTable);
54 XMLEventExport::~XMLEventExport()
56 // delete all handlers
57 HandlerMap::iterator aEnd = aHandlerMap.end();
58 for( HandlerMap::iterator aIter =
59 aHandlerMap.begin();
60 aIter != aEnd;
61 ++aIter )
63 delete aIter->second;
65 aHandlerMap.clear();
68 void XMLEventExport::AddHandler( const OUString& rName,
69 XMLEventExportHandler* pHandler )
71 DBG_ASSERT(pHandler != NULL, "Need EventExportHandler");
72 if (pHandler != NULL)
74 aHandlerMap[rName] = pHandler;
78 void XMLEventExport::AddTranslationTable(
79 const XMLEventNameTranslation* pTransTable )
81 if (NULL != pTransTable)
83 // put translation table into map
84 for(const XMLEventNameTranslation* pTrans = pTransTable;
85 pTrans->sAPIName != NULL;
86 pTrans++)
88 aNameTranslationMap[OUString::createFromAscii(pTrans->sAPIName)] =
89 XMLEventName(pTrans->nPrefix, pTrans->sXMLName);
92 // else? ignore!
95 void XMLEventExport::Export( Reference<XEventsSupplier> & rSupplier,
96 bool bWhitespace)
98 if (rSupplier.is())
100 Reference<XNameAccess> xAccess(rSupplier->getEvents(), UNO_QUERY);
101 Export(xAccess, bWhitespace);
103 // else: no supplier, no export -> ignore!
106 void XMLEventExport::Export( Reference<XNameReplace> & rReplace,
107 bool bWhitespace)
109 Reference<XNameAccess> xAccess(rReplace, UNO_QUERY);
110 Export(xAccess, bWhitespace);
113 void XMLEventExport::Export( Reference<XNameAccess> & rAccess,
114 bool bWhitespace)
116 // early out if we don't actually get any events
117 if (!rAccess.is())
119 return;
122 // have we already processed an element?
123 bool bStarted = false;
125 // iterate over all event types
126 Sequence<OUString> aNames = rAccess->getElementNames();
127 sal_Int32 nCount = aNames.getLength();
128 for(sal_Int32 i = 0; i < nCount; i++)
130 // translate name
131 NameMap::iterator aIter = aNameTranslationMap.find(aNames[i]);
132 if (aIter != aNameTranslationMap.end())
134 const XMLEventName& rXmlName = aIter->second;
136 // get PropertyValues for this event
137 Any aAny = rAccess->getByName( aNames[i] );
138 Sequence<PropertyValue> aValues;
139 aAny >>= aValues;
141 // now export the current event
142 ExportEvent( aValues, rXmlName, bWhitespace, bStarted );
144 #ifdef DBG_UTIL
145 else
147 // don't proceed further
148 OString aStr("Unknown event name:" );
149 aStr += OUStringToOString( aNames[i], RTL_TEXTENCODING_UTF8 );
150 OSL_FAIL( aStr.getStr() );
152 #endif
155 // close <script:events> element (if it was opened before)
156 if (bStarted)
158 EndElement(bWhitespace);
162 void XMLEventExport::ExportExt( Reference<XNameAccess> & rAccess,
163 bool bWhitespace )
165 // set bExtNamespace flag to use XML_NAMESPACE_OFFICE_EXT namespace
166 // for events element (not for child elements)
167 bExtNamespace = true;
168 Export(rAccess, bWhitespace);
169 bExtNamespace = false; // reset for future Export calls
172 /// export a singular event and wirte <office:events> container
173 void XMLEventExport::ExportSingleEvent(
174 Sequence<PropertyValue>& rEventValues,
175 const OUString& rApiEventName,
176 bool bUseWhitespace )
178 // translate the name
179 NameMap::iterator aIter = aNameTranslationMap.find(rApiEventName);
180 if (aIter != aNameTranslationMap.end())
182 const XMLEventName& rXmlName = aIter->second;
184 // export the event ...
185 bool bStarted = false;
186 ExportEvent( rEventValues, rXmlName, bUseWhitespace, bStarted );
188 // ... and close the container element (if necessary)
189 if (bStarted)
191 EndElement(bUseWhitespace);
194 #ifdef DBG_UTIL
195 else
197 // don't proceed further
198 OString aStr("Unknown event name:" );
199 aStr += OUStringToOString( rApiEventName, RTL_TEXTENCODING_UTF8 );
200 OSL_FAIL( aStr.getStr() );
202 #endif
206 /// export a single event
207 void XMLEventExport::ExportEvent(
208 Sequence<PropertyValue>& rEventValues,
209 const XMLEventName& rXmlEventName,
210 bool bUseWhitespace,
211 bool& rExported )
213 // search for EventType value and then delegate to EventHandler
214 sal_Int32 nValues = rEventValues.getLength();
215 const PropertyValue* pValues = rEventValues.getConstArray();
217 for(sal_Int32 nVal = 0; nVal < nValues; nVal++)
219 if (sEventType.equals(pValues[nVal].Name))
221 // found! Now find handler and delegate
222 OUString sType;
223 pValues[nVal].Value >>= sType;
225 if (aHandlerMap.count(sType))
227 if (! rExported)
229 // OK, we have't yet exported the enclosing
230 // element. So we do that now.
231 rExported = true;
232 StartElement(bUseWhitespace);
235 OUString aEventQName(
236 rExport.GetNamespaceMap().GetQNameByKey(
237 rXmlEventName.m_nPrefix, rXmlEventName.m_aName ) );
239 // delegate to proper ExportEventHandler
240 aHandlerMap[sType]->Export(rExport, aEventQName,
241 rEventValues, bUseWhitespace);
243 else
245 if ( sType != "None" )
247 OSL_FAIL("unknown event type returned by API");
248 // unknown type -> error (ignore)
250 // else: we ignore None fields
253 // early out: we don't need to look for another type
254 break;
256 // else: we only care for EventType -> ignore
261 void XMLEventExport::StartElement(bool bWhitespace)
263 if (bWhitespace)
265 rExport.IgnorableWhitespace();
267 sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT
268 : XML_NAMESPACE_OFFICE;
269 rExport.StartElement( nNamespace, XML_EVENT_LISTENERS,
270 bWhitespace);
273 void XMLEventExport::EndElement(bool bWhitespace)
275 sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT
276 : XML_NAMESPACE_OFFICE;
277 rExport.EndElement(nNamespace, XML_EVENT_LISTENERS, bWhitespace);
278 if (bWhitespace)
280 rExport.IgnorableWhitespace();
285 // implement aStandardEventTable (defined in xmlevent.hxx)
286 const XMLEventNameTranslation aStandardEventTable[] =
288 { "OnSelect", XML_NAMESPACE_DOM, "select" }, // "on-select"
289 { "OnInsertStart", XML_NAMESPACE_OFFICE, "insert-start" }, // "on-insert-start"
290 { "OnInsertDone", XML_NAMESPACE_OFFICE, "insert-done" }, // "on-insert-done"
291 { "OnMailMerge", XML_NAMESPACE_OFFICE, "mail-merge" }, // "on-mail-merge"
292 { "OnAlphaCharInput", XML_NAMESPACE_OFFICE, "alpha-char-input" }, // "on-alpha-char-input"
293 { "OnNonAlphaCharInput", XML_NAMESPACE_OFFICE, "non-alpha-char-input" }, // "on-non-alpha-char-input"
294 { "OnResize", XML_NAMESPACE_DOM, "resize" }, // "on-resize"
295 { "OnMove", XML_NAMESPACE_OFFICE, "move" }, // "on-move"
296 { "OnPageCountChange", XML_NAMESPACE_OFFICE, "page-count-change" }, // "on-page-count-change"
297 { "OnMouseOver", XML_NAMESPACE_DOM, "mouseover" }, // "on-mouse-over"
298 { "OnClick", XML_NAMESPACE_DOM, "click" }, // "on-click"
299 { "OnMouseOut", XML_NAMESPACE_DOM, "mouseout" }, // "on-mouse-out"
300 { "OnLoadError", XML_NAMESPACE_OFFICE, "load-error" }, // "on-load-error"
301 { "OnLoadCancel", XML_NAMESPACE_OFFICE, "load-cancel" }, // "on-load-cancel"
302 { "OnLoadDone", XML_NAMESPACE_OFFICE, "load-done" }, // "on-load-done"
303 { "OnLoad", XML_NAMESPACE_DOM, "load" }, // "on-load"
304 { "OnUnload", XML_NAMESPACE_DOM, "unload" }, // "on-unload"
305 { "OnStartApp", XML_NAMESPACE_OFFICE, "start-app" }, // "on-start-app"
306 { "OnCloseApp", XML_NAMESPACE_OFFICE, "close-app" }, // "on-close-app"
307 { "OnNew", XML_NAMESPACE_OFFICE, "new" }, // "on-new"
308 { "OnSave", XML_NAMESPACE_OFFICE, "save" }, // "on-save"
309 { "OnSaveAs", XML_NAMESPACE_OFFICE, "save-as" }, // "on-save-as"
310 { "OnFocus", XML_NAMESPACE_DOM, "DOMFocusIn" }, // "on-focus"
311 { "OnUnfocus", XML_NAMESPACE_DOM, "DOMFocusOut" }, // "on-unfocus"
312 { "OnPrint", XML_NAMESPACE_OFFICE, "print" }, // "on-print"
313 { "OnError", XML_NAMESPACE_DOM, "error" }, // "on-error"
314 { "OnLoadFinished", XML_NAMESPACE_OFFICE, "load-finished" }, // "on-load-finished"
315 { "OnSaveFinished", XML_NAMESPACE_OFFICE, "save-finished" }, // "on-save-finished"
316 { "OnModifyChanged", XML_NAMESPACE_OFFICE, "modify-changed" }, // "on-modify-changed"
317 { "OnPrepareUnload", XML_NAMESPACE_OFFICE, "prepare-unload" }, // "on-prepare-unload"
318 { "OnNewMail", XML_NAMESPACE_OFFICE, "new-mail" }, // "on-new-mail"
319 { "OnToggleFullscreen", XML_NAMESPACE_OFFICE, "toggle-fullscreen" }, // "on-toggle-fullscreen"
320 { "OnSaveDone", XML_NAMESPACE_OFFICE, "save-done" }, // "on-save-done"
321 { "OnSaveAsDone", XML_NAMESPACE_OFFICE, "save-as-done" }, // "on-save-as-done"
322 { "OnCopyTo", XML_NAMESPACE_OFFICE, "copy-to" },
323 { "OnCopyToDone", XML_NAMESPACE_OFFICE, "copy-to-done" },
324 { "OnViewCreated", XML_NAMESPACE_OFFICE, "view-created" },
325 { "OnPrepareViewClosing", XML_NAMESPACE_OFFICE, "prepare-view-closing" },
326 { "OnViewClosed", XML_NAMESPACE_OFFICE, "view-close" },
327 { "OnVisAreaChanged", XML_NAMESPACE_OFFICE, "visarea-changed" }, // "on-visarea-changed"
328 { "OnCreate", XML_NAMESPACE_OFFICE, "create" },
329 { "OnSaveAsFailed", XML_NAMESPACE_OFFICE, "save-as-failed" },
330 { "OnSaveFailed", XML_NAMESPACE_OFFICE, "save-failed" },
331 { "OnCopyToFailed", XML_NAMESPACE_OFFICE, "copy-to-failed" },
332 { "OnTitleChanged", XML_NAMESPACE_OFFICE, "title-changed" },
333 { "OnModeChanged", XML_NAMESPACE_OFFICE, "mode-changed" },
334 { "OnSaveTo", XML_NAMESPACE_OFFICE, "save-to" },
335 { "OnSaveToDone", XML_NAMESPACE_OFFICE, "save-to-done" },
336 { "OnSaveToFailed", XML_NAMESPACE_OFFICE, "save-to-failed" },
337 { "OnSubComponentOpened", XML_NAMESPACE_OFFICE, "subcomponent-opened" },
338 { "OnSubComponentClosed", XML_NAMESPACE_OFFICE, "subcomponent-closed" },
339 { "OnStorageChanged", XML_NAMESPACE_OFFICE, "storage-changed" },
340 { "OnMailMergeFinished", XML_NAMESPACE_OFFICE, "mail-merge-finished" },
341 { "OnFieldMerge", XML_NAMESPACE_OFFICE, "field-merge" },
342 { "OnFieldMergeFinished", XML_NAMESPACE_OFFICE, "field-merge-finished" },
343 { "OnLayoutFinished", XML_NAMESPACE_OFFICE, "layout-finished" },
344 { "OnDoubleClick", XML_NAMESPACE_OFFICE, "dblclick" },
345 { "OnRightClick", XML_NAMESPACE_OFFICE, "contextmenu" },
346 { "OnChange", XML_NAMESPACE_OFFICE, "content-changed" },
347 { "OnCalculate", XML_NAMESPACE_OFFICE, "calculated" },
349 { NULL, 0, 0 }
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */