/src/libreoffice/xmloff/source/script/XMLEventExport.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #include <xmloff/XMLEventExport.hxx> |
21 | | |
22 | | #include <com/sun/star/beans/PropertyValue.hpp> |
23 | | |
24 | | #include <com/sun/star/document/XEventsSupplier.hpp> |
25 | | |
26 | | #include <com/sun/star/container/XNameReplace.hpp> |
27 | | #include <sal/log.hxx> |
28 | | #include <osl/diagnose.h> |
29 | | #include <xmloff/xmlexp.hxx> |
30 | | #include <xmloff/xmltoken.hxx> |
31 | | #include <xmloff/xmlnamespace.hxx> |
32 | | #include <xmloff/namespacemap.hxx> |
33 | | |
34 | | |
35 | | using namespace ::com::sun::star::uno; |
36 | | |
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; |
42 | | |
43 | | XMLEventExport::XMLEventExport(SvXMLExport& rExp) : |
44 | 0 | m_rExport(rExp), |
45 | 0 | m_bExtNamespace(false) |
46 | 0 | { |
47 | 0 | } |
48 | | |
49 | | XMLEventExport::~XMLEventExport() |
50 | 0 | { |
51 | | // delete all handlers |
52 | 0 | m_aHandlerMap.clear(); |
53 | 0 | } |
54 | | |
55 | | void XMLEventExport::AddHandler( const OUString& rName, |
56 | | std::unique_ptr<XMLEventExportHandler> pHandler ) |
57 | 0 | { |
58 | 0 | assert(pHandler); |
59 | 0 | m_aHandlerMap[rName] = std::move(pHandler); |
60 | 0 | } |
61 | | |
62 | | void XMLEventExport::AddTranslationTable( |
63 | | const XMLEventNameTranslation* pTransTable ) |
64 | 0 | { |
65 | 0 | if (nullptr != pTransTable) |
66 | 0 | { |
67 | | // put translation table into map |
68 | 0 | for(const XMLEventNameTranslation* pTrans = pTransTable; |
69 | 0 | !pTrans->sAPIName.isEmpty(); |
70 | 0 | pTrans++) |
71 | 0 | { |
72 | 0 | m_aNameTranslationMap[pTrans->sAPIName] = |
73 | 0 | XMLEventName(pTrans->nPrefix, pTrans->sXMLName); |
74 | 0 | } |
75 | 0 | } |
76 | | // else? ignore! |
77 | 0 | } |
78 | | |
79 | | void XMLEventExport::Export( Reference<XEventsSupplier> const & rSupplier, |
80 | | bool bWhitespace) |
81 | 0 | { |
82 | 0 | if (rSupplier.is()) |
83 | 0 | { |
84 | 0 | Export(rSupplier->getEvents(), bWhitespace); |
85 | 0 | } |
86 | | // else: no supplier, no export -> ignore! |
87 | 0 | } |
88 | | |
89 | | void XMLEventExport::Export( Reference<XNameReplace> const & rReplace, |
90 | | bool bWhitespace) |
91 | 0 | { |
92 | 0 | Reference<XNameAccess> xAccess(rReplace); |
93 | 0 | Export(xAccess, bWhitespace); |
94 | 0 | } |
95 | | |
96 | | void XMLEventExport::Export( Reference<XNameAccess> const & rAccess, |
97 | | bool bWhitespace) |
98 | 0 | { |
99 | | // early out if we don't actually get any events |
100 | 0 | if (!rAccess.is()) |
101 | 0 | { |
102 | 0 | return; |
103 | 0 | } |
104 | | |
105 | | // have we already processed an element? |
106 | 0 | bool bStarted = false; |
107 | | |
108 | | // iterate over all event types |
109 | 0 | const Sequence<OUString> aNames = rAccess->getElementNames(); |
110 | 0 | for(const auto& rName : aNames) |
111 | 0 | { |
112 | | // translate name |
113 | 0 | NameMap::iterator aIter = m_aNameTranslationMap.find(rName); |
114 | 0 | if (aIter != m_aNameTranslationMap.end()) |
115 | 0 | { |
116 | 0 | const XMLEventName& rXmlName = aIter->second; |
117 | | |
118 | | // get PropertyValues for this event |
119 | 0 | Any aAny = rAccess->getByName( rName ); |
120 | 0 | Sequence<PropertyValue> aValues; |
121 | 0 | aAny >>= aValues; |
122 | | |
123 | | // now export the current event |
124 | 0 | ExportEvent( aValues, rXmlName, bWhitespace, bStarted ); |
125 | 0 | } |
126 | 0 | else |
127 | 0 | { |
128 | | // don't proceed further |
129 | 0 | SAL_WARN("xmloff", "Unknown event name:" << rName ); |
130 | 0 | } |
131 | 0 | } |
132 | | |
133 | | // close <script:events> element (if it was opened before) |
134 | 0 | if (bStarted) |
135 | 0 | { |
136 | 0 | EndElement(bWhitespace); |
137 | 0 | } |
138 | 0 | } |
139 | | |
140 | | void XMLEventExport::ExportExt( Reference<XNameAccess> const & rAccess ) |
141 | 0 | { |
142 | | // set bExtNamespace flag to use XML_NAMESPACE_OFFICE_EXT namespace |
143 | | // for events element (not for child elements) |
144 | 0 | m_bExtNamespace = true; |
145 | 0 | Export(rAccess); |
146 | 0 | m_bExtNamespace = false; // reset for future Export calls |
147 | 0 | } |
148 | | |
149 | | /// export a singular event and write <office:events> container |
150 | | void XMLEventExport::ExportSingleEvent( |
151 | | const Sequence<PropertyValue>& rEventValues, |
152 | | const OUString& rApiEventName, |
153 | | bool bUseWhitespace ) |
154 | 0 | { |
155 | | // translate the name |
156 | 0 | NameMap::iterator aIter = m_aNameTranslationMap.find(rApiEventName); |
157 | 0 | if (aIter != m_aNameTranslationMap.end()) |
158 | 0 | { |
159 | 0 | const XMLEventName& rXmlName = aIter->second; |
160 | | |
161 | | // export the event ... |
162 | 0 | bool bStarted = false; |
163 | 0 | ExportEvent( rEventValues, rXmlName, bUseWhitespace, bStarted ); |
164 | | |
165 | | // ... and close the container element (if necessary) |
166 | 0 | if (bStarted) |
167 | 0 | { |
168 | 0 | EndElement(bUseWhitespace); |
169 | 0 | } |
170 | 0 | } |
171 | 0 | else |
172 | 0 | { |
173 | | // don't proceed further |
174 | 0 | SAL_WARN("xmloff", "Unknown event name:" << rApiEventName ); |
175 | 0 | } |
176 | 0 | } |
177 | | |
178 | | |
179 | | /// export a single event |
180 | | void XMLEventExport::ExportEvent( |
181 | | const Sequence<PropertyValue>& rEventValues, |
182 | | const XMLEventName& rXmlEventName, |
183 | | bool bUseWhitespace, |
184 | | bool& rExported ) |
185 | 0 | { |
186 | | // search for EventType value and then delegate to EventHandler |
187 | 0 | const PropertyValue* pValue = std::find_if(rEventValues.begin(), rEventValues.end(), |
188 | 0 | [](const PropertyValue& rValue) { return u"EventType" == rValue.Name; }); |
189 | |
|
190 | 0 | if (pValue == rEventValues.end()) |
191 | 0 | return; |
192 | | |
193 | | // found! Now find handler and delegate |
194 | 0 | OUString sType; |
195 | 0 | pValue->Value >>= sType; |
196 | |
|
197 | 0 | if (m_aHandlerMap.count(sType)) |
198 | 0 | { |
199 | 0 | if (! rExported) |
200 | 0 | { |
201 | | // OK, we have't yet exported the enclosing |
202 | | // element. So we do that now. |
203 | 0 | rExported = true; |
204 | 0 | StartElement(bUseWhitespace); |
205 | 0 | } |
206 | |
|
207 | 0 | OUString aEventQName( |
208 | 0 | m_rExport.GetNamespaceMap().GetQNameByKey( |
209 | 0 | rXmlEventName.m_nPrefix, rXmlEventName.m_aName ) ); |
210 | | |
211 | | // delegate to proper ExportEventHandler |
212 | 0 | m_aHandlerMap[sType]->Export(m_rExport, aEventQName, |
213 | 0 | rEventValues, bUseWhitespace); |
214 | 0 | } |
215 | 0 | else |
216 | 0 | { |
217 | 0 | if ( sType != "None" ) |
218 | 0 | { |
219 | 0 | OSL_FAIL("unknown event type returned by API"); |
220 | | // unknown type -> error (ignore) |
221 | 0 | } |
222 | | // else: we ignore None fields |
223 | 0 | } |
224 | 0 | } |
225 | | |
226 | | |
227 | | void XMLEventExport::StartElement(bool bWhitespace) |
228 | 0 | { |
229 | 0 | if (bWhitespace) |
230 | 0 | { |
231 | 0 | m_rExport.IgnorableWhitespace(); |
232 | 0 | } |
233 | 0 | sal_uInt16 nNamespace = m_bExtNamespace ? XML_NAMESPACE_OFFICE_EXT |
234 | 0 | : XML_NAMESPACE_OFFICE; |
235 | 0 | m_rExport.StartElement( nNamespace, XML_EVENT_LISTENERS, |
236 | 0 | bWhitespace); |
237 | 0 | } |
238 | | |
239 | | void XMLEventExport::EndElement(bool bWhitespace) |
240 | 0 | { |
241 | 0 | sal_uInt16 nNamespace = m_bExtNamespace ? XML_NAMESPACE_OFFICE_EXT |
242 | 0 | : XML_NAMESPACE_OFFICE; |
243 | 0 | m_rExport.EndElement(nNamespace, XML_EVENT_LISTENERS, bWhitespace); |
244 | 0 | if (bWhitespace) |
245 | 0 | { |
246 | 0 | m_rExport.IgnorableWhitespace(); |
247 | 0 | } |
248 | 0 | } |
249 | | |
250 | | |
251 | | // implement aStandardEventTable (defined in xmlevent.hxx) |
252 | | const XMLEventNameTranslation aStandardEventTable[] = |
253 | | { |
254 | | { u"OnSelect"_ustr, XML_NAMESPACE_DOM, u"select"_ustr }, // "on-select" |
255 | | { u"OnInsertStart"_ustr, XML_NAMESPACE_OFFICE, u"insert-start"_ustr }, // "on-insert-start" |
256 | | { u"OnInsertDone"_ustr, XML_NAMESPACE_OFFICE, u"insert-done"_ustr }, // "on-insert-done" |
257 | | { u"OnMailMerge"_ustr, XML_NAMESPACE_OFFICE, u"mail-merge"_ustr }, // "on-mail-merge" |
258 | | { u"OnAlphaCharInput"_ustr, XML_NAMESPACE_OFFICE, u"alpha-char-input"_ustr }, // "on-alpha-char-input" |
259 | | { u"OnNonAlphaCharInput"_ustr, XML_NAMESPACE_OFFICE, u"non-alpha-char-input"_ustr }, // "on-non-alpha-char-input" |
260 | | { u"OnResize"_ustr, XML_NAMESPACE_DOM, u"resize"_ustr }, // "on-resize" |
261 | | { u"OnMove"_ustr, XML_NAMESPACE_OFFICE, u"move"_ustr }, // "on-move" |
262 | | { u"OnPageCountChange"_ustr, XML_NAMESPACE_OFFICE, u"page-count-change"_ustr }, // "on-page-count-change" |
263 | | { u"OnMouseOver"_ustr, XML_NAMESPACE_DOM, u"mouseover"_ustr }, // "on-mouse-over" |
264 | | { u"OnClick"_ustr, XML_NAMESPACE_DOM, u"click"_ustr }, // "on-click" |
265 | | { u"OnMouseOut"_ustr, XML_NAMESPACE_DOM, u"mouseout"_ustr }, // "on-mouse-out" |
266 | | { u"OnLoadError"_ustr, XML_NAMESPACE_OFFICE, u"load-error"_ustr }, // "on-load-error" |
267 | | { u"OnLoadCancel"_ustr, XML_NAMESPACE_OFFICE, u"load-cancel"_ustr }, // "on-load-cancel" |
268 | | { u"OnLoadDone"_ustr, XML_NAMESPACE_OFFICE, u"load-done"_ustr }, // "on-load-done" |
269 | | { u"OnLoad"_ustr, XML_NAMESPACE_DOM, u"load"_ustr }, // "on-load" |
270 | | { u"OnUnload"_ustr, XML_NAMESPACE_DOM, u"unload"_ustr }, // "on-unload" |
271 | | { u"OnStartApp"_ustr, XML_NAMESPACE_OFFICE, u"start-app"_ustr }, // "on-start-app" |
272 | | { u"OnCloseApp"_ustr, XML_NAMESPACE_OFFICE, u"close-app"_ustr }, // "on-close-app" |
273 | | { u"OnNew"_ustr, XML_NAMESPACE_OFFICE, u"new"_ustr }, // "on-new" |
274 | | { u"OnSave"_ustr, XML_NAMESPACE_OFFICE, u"save"_ustr }, // "on-save" |
275 | | { u"OnSaveAs"_ustr, XML_NAMESPACE_OFFICE, u"save-as"_ustr }, // "on-save-as" |
276 | | { u"OnFocus"_ustr, XML_NAMESPACE_DOM, u"DOMFocusIn"_ustr }, // "on-focus" |
277 | | { u"OnUnfocus"_ustr, XML_NAMESPACE_DOM, u"DOMFocusOut"_ustr }, // "on-unfocus" |
278 | | { u"OnPrint"_ustr, XML_NAMESPACE_OFFICE, u"print"_ustr }, // "on-print" |
279 | | { u"OnError"_ustr, XML_NAMESPACE_DOM, u"error"_ustr }, // "on-error" |
280 | | { u"OnLoadFinished"_ustr, XML_NAMESPACE_OFFICE, u"load-finished"_ustr }, // "on-load-finished" |
281 | | { u"OnSaveFinished"_ustr, XML_NAMESPACE_OFFICE, u"save-finished"_ustr }, // "on-save-finished" |
282 | | { u"OnModifyChanged"_ustr, XML_NAMESPACE_OFFICE, u"modify-changed"_ustr }, // "on-modify-changed" |
283 | | { u"OnPrepareUnload"_ustr, XML_NAMESPACE_OFFICE, u"prepare-unload"_ustr }, // "on-prepare-unload" |
284 | | { u"OnNewMail"_ustr, XML_NAMESPACE_OFFICE, u"new-mail"_ustr }, // "on-new-mail" |
285 | | { u"OnToggleFullscreen"_ustr, XML_NAMESPACE_OFFICE, u"toggle-fullscreen"_ustr }, // "on-toggle-fullscreen" |
286 | | { u"OnSaveDone"_ustr, XML_NAMESPACE_OFFICE, u"save-done"_ustr }, // "on-save-done" |
287 | | { u"OnSaveAsDone"_ustr, XML_NAMESPACE_OFFICE, u"save-as-done"_ustr }, // "on-save-as-done" |
288 | | { u"OnCopyTo"_ustr, XML_NAMESPACE_OFFICE, u"copy-to"_ustr }, |
289 | | { u"OnCopyToDone"_ustr, XML_NAMESPACE_OFFICE, u"copy-to-done"_ustr }, |
290 | | { u"OnViewCreated"_ustr, XML_NAMESPACE_OFFICE, u"view-created"_ustr }, |
291 | | { u"OnPrepareViewClosing"_ustr, XML_NAMESPACE_OFFICE, u"prepare-view-closing"_ustr }, |
292 | | { u"OnViewClosed"_ustr, XML_NAMESPACE_OFFICE, u"view-close"_ustr }, |
293 | | { u"OnVisAreaChanged"_ustr, XML_NAMESPACE_OFFICE, u"visarea-changed"_ustr }, // "on-visarea-changed" |
294 | | { u"OnCreate"_ustr, XML_NAMESPACE_OFFICE, u"create"_ustr }, |
295 | | { u"OnSaveAsFailed"_ustr, XML_NAMESPACE_OFFICE, u"save-as-failed"_ustr }, |
296 | | { u"OnSaveFailed"_ustr, XML_NAMESPACE_OFFICE, u"save-failed"_ustr }, |
297 | | { u"OnCopyToFailed"_ustr, XML_NAMESPACE_OFFICE, u"copy-to-failed"_ustr }, |
298 | | { u"OnTitleChanged"_ustr, XML_NAMESPACE_OFFICE, u"title-changed"_ustr }, |
299 | | { u"OnModeChanged"_ustr, XML_NAMESPACE_OFFICE, u"mode-changed"_ustr }, |
300 | | { u"OnSaveTo"_ustr, XML_NAMESPACE_OFFICE, u"save-to"_ustr }, |
301 | | { u"OnSaveToDone"_ustr, XML_NAMESPACE_OFFICE, u"save-to-done"_ustr }, |
302 | | { u"OnSaveToFailed"_ustr, XML_NAMESPACE_OFFICE, u"save-to-failed"_ustr }, |
303 | | { u"OnSubComponentOpened"_ustr, XML_NAMESPACE_OFFICE, u"subcomponent-opened"_ustr }, |
304 | | { u"OnSubComponentClosed"_ustr, XML_NAMESPACE_OFFICE, u"subcomponent-closed"_ustr }, |
305 | | { u"OnStorageChanged"_ustr, XML_NAMESPACE_OFFICE, u"storage-changed"_ustr }, |
306 | | { u"OnMailMergeFinished"_ustr, XML_NAMESPACE_OFFICE, u"mail-merge-finished"_ustr }, |
307 | | { u"OnFieldMerge"_ustr, XML_NAMESPACE_OFFICE, u"field-merge"_ustr }, |
308 | | { u"OnFieldMergeFinished"_ustr, XML_NAMESPACE_OFFICE, u"field-merge-finished"_ustr }, |
309 | | { u"OnLayoutFinished"_ustr, XML_NAMESPACE_OFFICE, u"layout-finished"_ustr }, |
310 | | { u"OnDoubleClick"_ustr, XML_NAMESPACE_OFFICE, u"dblclick"_ustr }, |
311 | | { u"OnRightClick"_ustr, XML_NAMESPACE_OFFICE, u"contextmenu"_ustr }, |
312 | | { u"OnChange"_ustr, XML_NAMESPACE_OFFICE, u"content-changed"_ustr }, |
313 | | { u"OnCalculate"_ustr, XML_NAMESPACE_OFFICE, u"calculated"_ustr }, |
314 | | |
315 | | { u""_ustr, 0, u""_ustr } |
316 | | }; |
317 | | |
318 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |