Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <xmloff/XMLEventExport.hxx>
30 : :
31 : : #include <com/sun/star/beans/PropertyValue.hpp>
32 : :
33 : : #include <com/sun/star/document/XEventsSupplier.hpp>
34 : :
35 : : #include <com/sun/star/container/XNameReplace.hpp>
36 : : #include <tools/debug.hxx>
37 : : #include <xmloff/xmlexp.hxx>
38 : : #include <xmloff/xmltoken.hxx>
39 : : #include "xmloff/xmlnmspe.hxx"
40 : : #include <xmloff/nmspmap.hxx>
41 : :
42 : :
43 : : using namespace ::com::sun::star::uno;
44 : :
45 : : using std::map;
46 : : using ::rtl::OUString;
47 : : using ::com::sun::star::beans::PropertyValue;
48 : : using ::com::sun::star::document::XEventsSupplier;
49 : : using ::com::sun::star::container::XNameReplace;
50 : : using ::com::sun::star::container::XNameAccess;
51 : : using ::xmloff::token::GetXMLToken;
52 : : using ::xmloff::token::XML_EVENT_LISTENERS;
53 : :
54 : :
55 : 242 : XMLEventExport::XMLEventExport(SvXMLExport& rExp,
56 : : const XMLEventNameTranslation* pTranslationTable) :
57 : : sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
58 : : rExport(rExp),
59 [ + - ][ + - ]: 242 : bExtNamespace(false)
60 : : {
61 [ + - ]: 242 : AddTranslationTable(pTranslationTable);
62 : 242 : }
63 : :
64 : 242 : XMLEventExport::~XMLEventExport()
65 : : {
66 : : // delete all handlers
67 : 242 : HandlerMap::iterator aEnd = aHandlerMap.end();
68 [ + + ]: 726 : for( HandlerMap::iterator aIter =
69 : 242 : aHandlerMap.begin();
70 : : aIter != aEnd;
71 : : ++aIter )
72 : : {
73 [ + - ][ + - ]: 484 : delete aIter->second;
74 : : }
75 : 242 : aHandlerMap.clear();
76 : 242 : }
77 : :
78 : 484 : void XMLEventExport::AddHandler( const OUString& rName,
79 : : XMLEventExportHandler* pHandler )
80 : : {
81 : : DBG_ASSERT(pHandler != NULL, "Need EventExportHandler");
82 [ + - ]: 484 : if (pHandler != NULL)
83 : : {
84 : 484 : aHandlerMap[rName] = pHandler;
85 : : }
86 : 484 : }
87 : :
88 : 527 : void XMLEventExport::AddTranslationTable(
89 : : const XMLEventNameTranslation* pTransTable )
90 : : {
91 [ + + ]: 527 : if (NULL != pTransTable)
92 : : {
93 : : // put translation table into map
94 [ + + ]: 16224 : for(const XMLEventNameTranslation* pTrans = pTransTable;
95 : : pTrans->sAPIName != NULL;
96 : : pTrans++)
97 : : {
98 [ + - ]: 31878 : aNameTranslationMap[OUString::createFromAscii(pTrans->sAPIName)] =
99 : 47817 : XMLEventName(pTrans->nPrefix, pTrans->sXMLName);
100 : : }
101 : : }
102 : : // else? ignore!
103 : 527 : }
104 : :
105 : 623 : void XMLEventExport::Export( Reference<XEventsSupplier> & rSupplier,
106 : : sal_Bool bWhitespace)
107 : : {
108 [ + + ]: 623 : if (rSupplier.is())
109 : : {
110 [ + - ][ + - ]: 211 : Reference<XNameAccess> xAccess(rSupplier->getEvents(), UNO_QUERY);
[ + - ]
111 [ + - ]: 211 : Export(xAccess, bWhitespace);
112 : : }
113 : : // else: no supplier, no export -> ignore!
114 : 623 : }
115 : :
116 : 0 : void XMLEventExport::Export( Reference<XNameReplace> & rReplace,
117 : : sal_Bool bWhitespace)
118 : : {
119 [ # # ]: 0 : Reference<XNameAccess> xAccess(rReplace, UNO_QUERY);
120 [ # # ]: 0 : Export(xAccess, bWhitespace);
121 : 0 : }
122 : :
123 : 211 : void XMLEventExport::Export( Reference<XNameAccess> & rAccess,
124 : : sal_Bool bWhitespace)
125 : : {
126 : : // early out if we don't actually get any events
127 [ + - ]: 211 : if (!rAccess.is())
128 : : {
129 : 211 : return;
130 : : }
131 : :
132 : : // have we already processed an element?
133 : 211 : sal_Bool bStarted = sal_False;
134 : :
135 : : // iterate over all event types
136 [ + - ][ + - ]: 211 : Sequence<OUString> aNames = rAccess->getElementNames();
137 : 211 : sal_Int32 nCount = aNames.getLength();
138 [ + + ]: 5549 : for(sal_Int32 i = 0; i < nCount; i++)
139 : : {
140 : : // translate name
141 [ + - ][ + - ]: 5338 : NameMap::iterator aIter = aNameTranslationMap.find(aNames[i]);
142 [ + - ]: 5338 : if (aIter != aNameTranslationMap.end())
143 : : {
144 : 5338 : const XMLEventName& rXmlName = aIter->second;
145 : :
146 : : // get PropertyValues for this event
147 [ + - ][ + - ]: 5338 : Any aAny = rAccess->getByName( aNames[i] );
[ + - ]
148 [ + - ]: 5338 : Sequence<PropertyValue> aValues;
149 [ + - ]: 5338 : aAny >>= aValues;
150 : :
151 : : // now export the current event
152 [ + - ][ + - ]: 5338 : ExportEvent( aValues, rXmlName, bWhitespace, bStarted );
153 : : }
154 : : #ifdef DBG_UTIL
155 : : else
156 : : {
157 : : // don't proceed further
158 : : ::rtl::OString aStr("Unknown event name:" );
159 : : aStr += ::rtl::OUStringToOString( aNames[i], RTL_TEXTENCODING_UTF8 );
160 : : OSL_FAIL( aStr.getStr() );
161 : : }
162 : : #endif
163 : : }
164 : :
165 : : // close <script:events> element (if it was opened before)
166 [ - + ]: 211 : if (bStarted)
167 : : {
168 [ # # ]: 0 : EndElement(bWhitespace);
169 [ + - ]: 211 : }
170 : : }
171 : :
172 : 0 : void XMLEventExport::ExportExt( Reference<XNameAccess> & rAccess,
173 : : sal_Bool bWhitespace )
174 : : {
175 : : // set bExtNamespace flag to use XML_NAMESPACE_OFFICE_EXT namespace
176 : : // for events element (not for child elements)
177 : 0 : bExtNamespace = true;
178 : 0 : Export(rAccess, bWhitespace);
179 : 0 : bExtNamespace = false; // reset for future Export calls
180 : 0 : }
181 : :
182 : : /// export a singular event and wirte <office:events> container
183 : 0 : void XMLEventExport::ExportSingleEvent(
184 : : Sequence<PropertyValue>& rEventValues,
185 : : const OUString& rApiEventName,
186 : : sal_Bool bUseWhitespace )
187 : : {
188 : : // translate the name
189 [ # # ]: 0 : NameMap::iterator aIter = aNameTranslationMap.find(rApiEventName);
190 [ # # ]: 0 : if (aIter != aNameTranslationMap.end())
191 : : {
192 : 0 : const XMLEventName& rXmlName = aIter->second;
193 : :
194 : : // export the event ...
195 : 0 : sal_Bool bStarted = sal_False;
196 [ # # ]: 0 : ExportEvent( rEventValues, rXmlName, bUseWhitespace, bStarted );
197 : :
198 : : // ... and close the container element (if necessary)
199 [ # # ]: 0 : if (bStarted)
200 : : {
201 [ # # ]: 0 : EndElement(bUseWhitespace);
202 : : }
203 : : }
204 : : #ifdef DBG_UTIL
205 : : else
206 : : {
207 : : // don't proceed further
208 : : ::rtl::OString aStr("Unknown event name:" );
209 : : aStr += ::rtl::OUStringToOString( rApiEventName, RTL_TEXTENCODING_UTF8 );
210 : : OSL_FAIL( aStr.getStr() );
211 : : }
212 : : #endif
213 : 0 : }
214 : :
215 : :
216 : : /// export a single event
217 : 5338 : void XMLEventExport::ExportEvent(
218 : : Sequence<PropertyValue>& rEventValues,
219 : : const XMLEventName& rXmlEventName,
220 : : sal_Bool bUseWhitespace,
221 : : sal_Bool& rExported )
222 : : {
223 : : // search for EventType value and then delegate to EventHandler
224 : 5338 : sal_Int32 nValues = rEventValues.getLength();
225 : 5338 : const PropertyValue* pValues = rEventValues.getConstArray();
226 : :
227 [ - + ]: 5338 : for(sal_Int32 nVal = 0; nVal < nValues; nVal++)
228 : : {
229 [ # # ]: 0 : if (sEventType.equals(pValues[nVal].Name))
230 : : {
231 : : // found! Now find handler and delegate
232 : 0 : OUString sType;
233 : 0 : pValues[nVal].Value >>= sType;
234 : :
235 [ # # ][ # # ]: 0 : if (aHandlerMap.count(sType))
236 : : {
237 [ # # ]: 0 : if (! rExported)
238 : : {
239 : : // OK, we have't yet exported the enclosing
240 : : // element. So we do that now.
241 : 0 : rExported = sal_True;
242 [ # # ]: 0 : StartElement(bUseWhitespace);
243 : : }
244 : :
245 : : OUString aEventQName(
246 : 0 : rExport.GetNamespaceMap().GetQNameByKey(
247 [ # # ]: 0 : rXmlEventName.m_nPrefix, rXmlEventName.m_aName ) );
248 : :
249 : : // delegate to proper ExportEventHandler
250 [ # # ]: 0 : aHandlerMap[sType]->Export(rExport, aEventQName,
251 [ # # ]: 0 : rEventValues, bUseWhitespace);
252 : : }
253 : : else
254 : : {
255 : 0 : if (! sType.equalsAsciiL("None", sizeof("None")-1))
256 : : {
257 : : OSL_FAIL("unknown event type returned by API");
258 : : // unknown type -> error (ignore)
259 : : }
260 : : // else: we ignore None fields
261 : : }
262 : :
263 : : // early out: we don't need to look for another type
264 : 0 : break;
265 : : }
266 : : // else: we only care for EventType -> ignore
267 : : }
268 : 5338 : }
269 : :
270 : :
271 : 0 : void XMLEventExport::StartElement(sal_Bool bWhitespace)
272 : : {
273 [ # # ]: 0 : if (bWhitespace)
274 : : {
275 : 0 : rExport.IgnorableWhitespace();
276 : : }
277 : : sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT
278 [ # # ]: 0 : : XML_NAMESPACE_OFFICE;
279 : : rExport.StartElement( nNamespace, XML_EVENT_LISTENERS,
280 : 0 : bWhitespace);
281 : 0 : }
282 : :
283 : 0 : void XMLEventExport::EndElement(sal_Bool bWhitespace)
284 : : {
285 : : sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT
286 [ # # ]: 0 : : XML_NAMESPACE_OFFICE;
287 : 0 : rExport.EndElement(nNamespace, XML_EVENT_LISTENERS, bWhitespace);
288 [ # # ]: 0 : if (bWhitespace)
289 : : {
290 : 0 : rExport.IgnorableWhitespace();
291 : : }
292 : 0 : }
293 : :
294 : :
295 : : // implement aStandardEventTable (defined in xmlevent.hxx)
296 : : const XMLEventNameTranslation aStandardEventTable[] =
297 : : {
298 : : { "OnSelect", XML_NAMESPACE_DOM, "select" }, // "on-select"
299 : : { "OnInsertStart", XML_NAMESPACE_OFFICE, "insert-start" }, // "on-insert-start"
300 : : { "OnInsertDone", XML_NAMESPACE_OFFICE, "insert-done" }, // "on-insert-done"
301 : : { "OnMailMerge", XML_NAMESPACE_OFFICE, "mail-merge" }, // "on-mail-merge"
302 : : { "OnAlphaCharInput", XML_NAMESPACE_OFFICE, "alpha-char-input" }, // "on-alpha-char-input"
303 : : { "OnNonAlphaCharInput", XML_NAMESPACE_OFFICE, "non-alpha-char-input" }, // "on-non-alpha-char-input"
304 : : { "OnResize", XML_NAMESPACE_DOM, "resize" }, // "on-resize"
305 : : { "OnMove", XML_NAMESPACE_OFFICE, "move" }, // "on-move"
306 : : { "OnPageCountChange", XML_NAMESPACE_OFFICE, "page-count-change" }, // "on-page-count-change"
307 : : { "OnMouseOver", XML_NAMESPACE_DOM, "mouseover" }, // "on-mouse-over"
308 : : { "OnClick", XML_NAMESPACE_DOM, "click" }, // "on-click"
309 : : { "OnMouseOut", XML_NAMESPACE_DOM, "mouseout" }, // "on-mouse-out"
310 : : { "OnLoadError", XML_NAMESPACE_OFFICE, "load-error" }, // "on-load-error"
311 : : { "OnLoadCancel", XML_NAMESPACE_OFFICE, "load-cancel" }, // "on-load-cancel"
312 : : { "OnLoadDone", XML_NAMESPACE_OFFICE, "load-done" }, // "on-load-done"
313 : : { "OnLoad", XML_NAMESPACE_DOM, "load" }, // "on-load"
314 : : { "OnUnload", XML_NAMESPACE_DOM, "unload" }, // "on-unload"
315 : : { "OnStartApp", XML_NAMESPACE_OFFICE, "start-app" }, // "on-start-app"
316 : : { "OnCloseApp", XML_NAMESPACE_OFFICE, "close-app" }, // "on-close-app"
317 : : { "OnNew", XML_NAMESPACE_OFFICE, "new" }, // "on-new"
318 : : { "OnSave", XML_NAMESPACE_OFFICE, "save" }, // "on-save"
319 : : { "OnSaveAs", XML_NAMESPACE_OFFICE, "save-as" }, // "on-save-as"
320 : : { "OnFocus", XML_NAMESPACE_DOM, "DOMFocusIn" }, // "on-focus"
321 : : { "OnUnfocus", XML_NAMESPACE_DOM, "DOMFocusOut" }, // "on-unfocus"
322 : : { "OnPrint", XML_NAMESPACE_OFFICE, "print" }, // "on-print"
323 : : { "OnError", XML_NAMESPACE_DOM, "error" }, // "on-error"
324 : : { "OnLoadFinished", XML_NAMESPACE_OFFICE, "load-finished" }, // "on-load-finished"
325 : : { "OnSaveFinished", XML_NAMESPACE_OFFICE, "save-finished" }, // "on-save-finished"
326 : : { "OnModifyChanged", XML_NAMESPACE_OFFICE, "modify-changed" }, // "on-modify-changed"
327 : : { "OnPrepareUnload", XML_NAMESPACE_OFFICE, "prepare-unload" }, // "on-prepare-unload"
328 : : { "OnNewMail", XML_NAMESPACE_OFFICE, "new-mail" }, // "on-new-mail"
329 : : { "OnToggleFullscreen", XML_NAMESPACE_OFFICE, "toggle-fullscreen" }, // "on-toggle-fullscreen"
330 : : { "OnSaveDone", XML_NAMESPACE_OFFICE, "save-done" }, // "on-save-done"
331 : : { "OnSaveAsDone", XML_NAMESPACE_OFFICE, "save-as-done" }, // "on-save-as-done"
332 : : { "OnCopyTo", XML_NAMESPACE_OFFICE, "copy-to" },
333 : : { "OnCopyToDone", XML_NAMESPACE_OFFICE, "copy-to-done" },
334 : : { "OnViewCreated", XML_NAMESPACE_OFFICE, "view-created" },
335 : : { "OnPrepareViewClosing", XML_NAMESPACE_OFFICE, "prepare-view-closing" },
336 : : { "OnViewClosed", XML_NAMESPACE_OFFICE, "view-close" },
337 : : { "OnVisAreaChanged", XML_NAMESPACE_OFFICE, "visarea-changed" }, // "on-visarea-changed"
338 : : { "OnCreate", XML_NAMESPACE_OFFICE, "create" },
339 : : { "OnSaveAsFailed", XML_NAMESPACE_OFFICE, "save-as-failed" },
340 : : { "OnSaveFailed", XML_NAMESPACE_OFFICE, "save-failed" },
341 : : { "OnCopyToFailed", XML_NAMESPACE_OFFICE, "copy-to-failed" },
342 : : { "OnTitleChanged", XML_NAMESPACE_OFFICE, "title-changed" },
343 : : { "OnModeChanged", XML_NAMESPACE_OFFICE, "mode-changed" },
344 : : { "OnSaveTo", XML_NAMESPACE_OFFICE, "save-to" },
345 : : { "OnSaveToDone", XML_NAMESPACE_OFFICE, "save-to-done" },
346 : : { "OnSaveToFailed", XML_NAMESPACE_OFFICE, "save-to-failed" },
347 : : { "OnSubComponentOpened", XML_NAMESPACE_OFFICE, "subcomponent-opened" },
348 : : { "OnSubComponentClosed", XML_NAMESPACE_OFFICE, "subcomponent-closed" },
349 : : { "OnStorageChanged", XML_NAMESPACE_OFFICE, "storage-changed" },
350 : : { "OnMailMergeFinished", XML_NAMESPACE_OFFICE, "mail-merge-finished" },
351 : : { "OnFieldMerge", XML_NAMESPACE_OFFICE, "field-merge" },
352 : : { "OnFieldMergeFinished", XML_NAMESPACE_OFFICE, "field-merge-finished" },
353 : : { "OnLayoutFinished", XML_NAMESPACE_OFFICE, "layout-finished" },
354 : : { "OnDoubleClick", XML_NAMESPACE_OFFICE, "dblclick" },
355 : : { "OnRightClick", XML_NAMESPACE_OFFICE, "contextmenu" },
356 : : { "OnChange", XML_NAMESPACE_OFFICE, "content-changed" },
357 : : { "OnCalculate", XML_NAMESPACE_OFFICE, "calculated" },
358 : :
359 : : { NULL, 0, 0 }
360 : : };
361 : :
362 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|