1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
;
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::XML_EVENT_LISTENERS
;
44 XMLEventExport::XMLEventExport(SvXMLExport
& rExp
) :
45 sEventType("EventType"),
51 XMLEventExport::~XMLEventExport()
53 // delete all handlers
54 HandlerMap::iterator aEnd
= aHandlerMap
.end();
55 for( HandlerMap::iterator aIter
=
65 void XMLEventExport::AddHandler( const OUString
& rName
,
66 XMLEventExportHandler
* pHandler
)
68 DBG_ASSERT(pHandler
!= nullptr, "Need EventExportHandler");
69 if (pHandler
!= nullptr)
71 aHandlerMap
[rName
] = pHandler
;
75 void XMLEventExport::AddTranslationTable(
76 const XMLEventNameTranslation
* pTransTable
)
78 if (nullptr != pTransTable
)
80 // put translation table into map
81 for(const XMLEventNameTranslation
* pTrans
= pTransTable
;
82 pTrans
->sAPIName
!= nullptr;
85 aNameTranslationMap
[OUString::createFromAscii(pTrans
->sAPIName
)] =
86 XMLEventName(pTrans
->nPrefix
, pTrans
->sXMLName
);
92 void XMLEventExport::Export( Reference
<XEventsSupplier
> & rSupplier
,
97 Reference
<XNameAccess
> xAccess(rSupplier
->getEvents(), UNO_QUERY
);
98 Export(xAccess
, bWhitespace
);
100 // else: no supplier, no export -> ignore!
103 void XMLEventExport::Export( Reference
<XNameReplace
> & rReplace
,
106 Reference
<XNameAccess
> xAccess(rReplace
, UNO_QUERY
);
107 Export(xAccess
, bWhitespace
);
110 void XMLEventExport::Export( Reference
<XNameAccess
> & rAccess
,
113 // early out if we don't actually get any events
119 // have we already processed an element?
120 bool bStarted
= false;
122 // iterate over all event types
123 Sequence
<OUString
> aNames
= rAccess
->getElementNames();
124 sal_Int32 nCount
= aNames
.getLength();
125 for(sal_Int32 i
= 0; i
< nCount
; i
++)
128 NameMap::iterator aIter
= aNameTranslationMap
.find(aNames
[i
]);
129 if (aIter
!= aNameTranslationMap
.end())
131 const XMLEventName
& rXmlName
= aIter
->second
;
133 // get PropertyValues for this event
134 Any aAny
= rAccess
->getByName( aNames
[i
] );
135 Sequence
<PropertyValue
> aValues
;
138 // now export the current event
139 ExportEvent( aValues
, rXmlName
, bWhitespace
, bStarted
);
144 // don't proceed further
145 OString
aStr("Unknown event name:" );
146 aStr
+= OUStringToOString( aNames
[i
], RTL_TEXTENCODING_UTF8
);
147 OSL_FAIL( aStr
.getStr() );
152 // close <script:events> element (if it was opened before)
155 EndElement(bWhitespace
);
159 void XMLEventExport::ExportExt( Reference
<XNameAccess
> & rAccess
)
161 // set bExtNamespace flag to use XML_NAMESPACE_OFFICE_EXT namespace
162 // for events element (not for child elements)
163 bExtNamespace
= true;
165 bExtNamespace
= false; // reset for future Export calls
168 /// export a singular event and wirte <office:events> container
169 void XMLEventExport::ExportSingleEvent(
170 Sequence
<PropertyValue
>& rEventValues
,
171 const OUString
& rApiEventName
,
172 bool bUseWhitespace
)
174 // translate the name
175 NameMap::iterator aIter
= aNameTranslationMap
.find(rApiEventName
);
176 if (aIter
!= aNameTranslationMap
.end())
178 const XMLEventName
& rXmlName
= aIter
->second
;
180 // export the event ...
181 bool bStarted
= false;
182 ExportEvent( rEventValues
, rXmlName
, bUseWhitespace
, bStarted
);
184 // ... and close the container element (if necessary)
187 EndElement(bUseWhitespace
);
193 // don't proceed further
194 OString
aStr("Unknown event name:" );
195 aStr
+= OUStringToOString( rApiEventName
, RTL_TEXTENCODING_UTF8
);
196 OSL_FAIL( aStr
.getStr() );
202 /// export a single event
203 void XMLEventExport::ExportEvent(
204 Sequence
<PropertyValue
>& rEventValues
,
205 const XMLEventName
& rXmlEventName
,
209 // search for EventType value and then delegate to EventHandler
210 sal_Int32 nValues
= rEventValues
.getLength();
211 const PropertyValue
* pValues
= rEventValues
.getConstArray();
213 for(sal_Int32 nVal
= 0; nVal
< nValues
; nVal
++)
215 if (sEventType
.equals(pValues
[nVal
].Name
))
217 // found! Now find handler and delegate
219 pValues
[nVal
].Value
>>= sType
;
221 if (aHandlerMap
.count(sType
))
225 // OK, we have't yet exported the enclosing
226 // element. So we do that now.
228 StartElement(bUseWhitespace
);
231 OUString
aEventQName(
232 rExport
.GetNamespaceMap().GetQNameByKey(
233 rXmlEventName
.m_nPrefix
, rXmlEventName
.m_aName
) );
235 // delegate to proper ExportEventHandler
236 aHandlerMap
[sType
]->Export(rExport
, aEventQName
,
237 rEventValues
, bUseWhitespace
);
241 if ( sType
!= "None" )
243 OSL_FAIL("unknown event type returned by API");
244 // unknown type -> error (ignore)
246 // else: we ignore None fields
249 // early out: we don't need to look for another type
252 // else: we only care for EventType -> ignore
257 void XMLEventExport::StartElement(bool bWhitespace
)
261 rExport
.IgnorableWhitespace();
263 sal_uInt16 nNamespace
= bExtNamespace
? XML_NAMESPACE_OFFICE_EXT
264 : XML_NAMESPACE_OFFICE
;
265 rExport
.StartElement( nNamespace
, XML_EVENT_LISTENERS
,
269 void XMLEventExport::EndElement(bool bWhitespace
)
271 sal_uInt16 nNamespace
= bExtNamespace
? XML_NAMESPACE_OFFICE_EXT
272 : XML_NAMESPACE_OFFICE
;
273 rExport
.EndElement(nNamespace
, XML_EVENT_LISTENERS
, bWhitespace
);
276 rExport
.IgnorableWhitespace();
281 // implement aStandardEventTable (defined in xmlevent.hxx)
282 const XMLEventNameTranslation aStandardEventTable
[] =
284 { "OnSelect", XML_NAMESPACE_DOM
, "select" }, // "on-select"
285 { "OnInsertStart", XML_NAMESPACE_OFFICE
, "insert-start" }, // "on-insert-start"
286 { "OnInsertDone", XML_NAMESPACE_OFFICE
, "insert-done" }, // "on-insert-done"
287 { "OnMailMerge", XML_NAMESPACE_OFFICE
, "mail-merge" }, // "on-mail-merge"
288 { "OnAlphaCharInput", XML_NAMESPACE_OFFICE
, "alpha-char-input" }, // "on-alpha-char-input"
289 { "OnNonAlphaCharInput", XML_NAMESPACE_OFFICE
, "non-alpha-char-input" }, // "on-non-alpha-char-input"
290 { "OnResize", XML_NAMESPACE_DOM
, "resize" }, // "on-resize"
291 { "OnMove", XML_NAMESPACE_OFFICE
, "move" }, // "on-move"
292 { "OnPageCountChange", XML_NAMESPACE_OFFICE
, "page-count-change" }, // "on-page-count-change"
293 { "OnMouseOver", XML_NAMESPACE_DOM
, "mouseover" }, // "on-mouse-over"
294 { "OnClick", XML_NAMESPACE_DOM
, "click" }, // "on-click"
295 { "OnMouseOut", XML_NAMESPACE_DOM
, "mouseout" }, // "on-mouse-out"
296 { "OnLoadError", XML_NAMESPACE_OFFICE
, "load-error" }, // "on-load-error"
297 { "OnLoadCancel", XML_NAMESPACE_OFFICE
, "load-cancel" }, // "on-load-cancel"
298 { "OnLoadDone", XML_NAMESPACE_OFFICE
, "load-done" }, // "on-load-done"
299 { "OnLoad", XML_NAMESPACE_DOM
, "load" }, // "on-load"
300 { "OnUnload", XML_NAMESPACE_DOM
, "unload" }, // "on-unload"
301 { "OnStartApp", XML_NAMESPACE_OFFICE
, "start-app" }, // "on-start-app"
302 { "OnCloseApp", XML_NAMESPACE_OFFICE
, "close-app" }, // "on-close-app"
303 { "OnNew", XML_NAMESPACE_OFFICE
, "new" }, // "on-new"
304 { "OnSave", XML_NAMESPACE_OFFICE
, "save" }, // "on-save"
305 { "OnSaveAs", XML_NAMESPACE_OFFICE
, "save-as" }, // "on-save-as"
306 { "OnFocus", XML_NAMESPACE_DOM
, "DOMFocusIn" }, // "on-focus"
307 { "OnUnfocus", XML_NAMESPACE_DOM
, "DOMFocusOut" }, // "on-unfocus"
308 { "OnPrint", XML_NAMESPACE_OFFICE
, "print" }, // "on-print"
309 { "OnError", XML_NAMESPACE_DOM
, "error" }, // "on-error"
310 { "OnLoadFinished", XML_NAMESPACE_OFFICE
, "load-finished" }, // "on-load-finished"
311 { "OnSaveFinished", XML_NAMESPACE_OFFICE
, "save-finished" }, // "on-save-finished"
312 { "OnModifyChanged", XML_NAMESPACE_OFFICE
, "modify-changed" }, // "on-modify-changed"
313 { "OnPrepareUnload", XML_NAMESPACE_OFFICE
, "prepare-unload" }, // "on-prepare-unload"
314 { "OnNewMail", XML_NAMESPACE_OFFICE
, "new-mail" }, // "on-new-mail"
315 { "OnToggleFullscreen", XML_NAMESPACE_OFFICE
, "toggle-fullscreen" }, // "on-toggle-fullscreen"
316 { "OnSaveDone", XML_NAMESPACE_OFFICE
, "save-done" }, // "on-save-done"
317 { "OnSaveAsDone", XML_NAMESPACE_OFFICE
, "save-as-done" }, // "on-save-as-done"
318 { "OnCopyTo", XML_NAMESPACE_OFFICE
, "copy-to" },
319 { "OnCopyToDone", XML_NAMESPACE_OFFICE
, "copy-to-done" },
320 { "OnViewCreated", XML_NAMESPACE_OFFICE
, "view-created" },
321 { "OnPrepareViewClosing", XML_NAMESPACE_OFFICE
, "prepare-view-closing" },
322 { "OnViewClosed", XML_NAMESPACE_OFFICE
, "view-close" },
323 { "OnVisAreaChanged", XML_NAMESPACE_OFFICE
, "visarea-changed" }, // "on-visarea-changed"
324 { "OnCreate", XML_NAMESPACE_OFFICE
, "create" },
325 { "OnSaveAsFailed", XML_NAMESPACE_OFFICE
, "save-as-failed" },
326 { "OnSaveFailed", XML_NAMESPACE_OFFICE
, "save-failed" },
327 { "OnCopyToFailed", XML_NAMESPACE_OFFICE
, "copy-to-failed" },
328 { "OnTitleChanged", XML_NAMESPACE_OFFICE
, "title-changed" },
329 { "OnModeChanged", XML_NAMESPACE_OFFICE
, "mode-changed" },
330 { "OnSaveTo", XML_NAMESPACE_OFFICE
, "save-to" },
331 { "OnSaveToDone", XML_NAMESPACE_OFFICE
, "save-to-done" },
332 { "OnSaveToFailed", XML_NAMESPACE_OFFICE
, "save-to-failed" },
333 { "OnSubComponentOpened", XML_NAMESPACE_OFFICE
, "subcomponent-opened" },
334 { "OnSubComponentClosed", XML_NAMESPACE_OFFICE
, "subcomponent-closed" },
335 { "OnStorageChanged", XML_NAMESPACE_OFFICE
, "storage-changed" },
336 { "OnMailMergeFinished", XML_NAMESPACE_OFFICE
, "mail-merge-finished" },
337 { "OnFieldMerge", XML_NAMESPACE_OFFICE
, "field-merge" },
338 { "OnFieldMergeFinished", XML_NAMESPACE_OFFICE
, "field-merge-finished" },
339 { "OnLayoutFinished", XML_NAMESPACE_OFFICE
, "layout-finished" },
340 { "OnDoubleClick", XML_NAMESPACE_OFFICE
, "dblclick" },
341 { "OnRightClick", XML_NAMESPACE_OFFICE
, "contextmenu" },
342 { "OnChange", XML_NAMESPACE_OFFICE
, "content-changed" },
343 { "OnCalculate", XML_NAMESPACE_OFFICE
, "calculated" },
345 { nullptr, 0, nullptr }
348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */