diff options
Diffstat (limited to 'xmloff/source/script/XMLEventExport.cxx')
-rw-r--r-- | xmloff/source/script/XMLEventExport.cxx | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/xmloff/source/script/XMLEventExport.cxx b/xmloff/source/script/XMLEventExport.cxx new file mode 100644 index 000000000000..ebb339348097 --- /dev/null +++ b/xmloff/source/script/XMLEventExport.cxx @@ -0,0 +1,364 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" +#include <xmloff/XMLEventExport.hxx> + +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <com/sun/star/document/XEventsSupplier.hpp> + +#include <com/sun/star/container/XNameReplace.hpp> +#include <tools/debug.hxx> +#include <xmloff/xmlexp.hxx> +#include <xmloff/xmltoken.hxx> +#include "xmloff/xmlnmspe.hxx" +#include <xmloff/nmspmap.hxx> + + +using namespace ::com::sun::star::uno; + +using std::map; +using ::rtl::OUString; +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::document::XEventsSupplier; +using ::com::sun::star::container::XNameReplace; +using ::com::sun::star::container::XNameAccess; +using ::xmloff::token::GetXMLToken; +using ::xmloff::token::XML_EVENT_LISTENERS; + + +XMLEventExport::XMLEventExport(SvXMLExport& rExp, + const XMLEventNameTranslation* pTranslationTable) : + sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")), + rExport(rExp), + bExtNamespace(false) +{ + AddTranslationTable(pTranslationTable); +} + +XMLEventExport::~XMLEventExport() +{ + // delete all handlers + HandlerMap::iterator aEnd = aHandlerMap.end(); + for( HandlerMap::iterator aIter = + aHandlerMap.begin(); + aIter != aEnd; + ++aIter ) + { + delete aIter->second; + } + aHandlerMap.clear(); +} + +void XMLEventExport::AddHandler( const OUString& rName, + XMLEventExportHandler* pHandler ) +{ + DBG_ASSERT(pHandler != NULL, "Need EventExportHandler"); + if (pHandler != NULL) + { + aHandlerMap[rName] = pHandler; + } +} + +void XMLEventExport::AddTranslationTable( + const XMLEventNameTranslation* pTransTable ) +{ + if (NULL != pTransTable) + { + // put translation table into map + for(const XMLEventNameTranslation* pTrans = pTransTable; + pTrans->sAPIName != NULL; + pTrans++) + { + aNameTranslationMap[OUString::createFromAscii(pTrans->sAPIName)] = + XMLEventName(pTrans->nPrefix, pTrans->sXMLName); + } + } + // else? ignore! +} + +void XMLEventExport::Export( Reference<XEventsSupplier> & rSupplier, + sal_Bool bWhitespace) +{ + if (rSupplier.is()) + { + Reference<XNameAccess> xAccess(rSupplier->getEvents(), UNO_QUERY); + Export(xAccess, bWhitespace); + } + // else: no supplier, no export -> ignore! +} + +void XMLEventExport::Export( Reference<XNameReplace> & rReplace, + sal_Bool bWhitespace) +{ + Reference<XNameAccess> xAccess(rReplace, UNO_QUERY); + Export(xAccess, bWhitespace); +} + +void XMLEventExport::Export( Reference<XNameAccess> & rAccess, + sal_Bool bWhitespace) +{ + // early out if we don't actually get any events + if (!rAccess.is()) + { + return; + } + + // have we already processed an element? + sal_Bool bStarted = sal_False; + + // iterate over all event types + Sequence<OUString> aNames = rAccess->getElementNames(); + sal_Int32 nCount = aNames.getLength(); + for(sal_Int32 i = 0; i < nCount; i++) + { + // translate name + NameMap::iterator aIter = aNameTranslationMap.find(aNames[i]); + if (aIter != aNameTranslationMap.end()) + { + const XMLEventName& rXmlName = aIter->second; + + // get PropertyValues for this event + Any aAny = rAccess->getByName( aNames[i] ); + Sequence<PropertyValue> aValues; + aAny >>= aValues; + + // now export the current event + ExportEvent( aValues, rXmlName, bWhitespace, bStarted ); + } +#ifdef DBG_UTIL + else + { + // don't proceed further + ::rtl::OString aStr("Unknown event name:" ); + aStr += ::rtl::OUStringToOString( aNames[i], RTL_TEXTENCODING_UTF8 ); + OSL_FAIL( aStr.getStr() ); + } +#endif + } + + // close <script:events> element (if it was opened before) + if (bStarted) + { + EndElement(bWhitespace); + } +} + +void XMLEventExport::ExportExt( Reference<XNameAccess> & rAccess, + sal_Bool bWhitespace ) +{ + // set bExtNamespace flag to use XML_NAMESPACE_OFFICE_EXT namespace + // for events element (not for child elements) + bExtNamespace = true; + Export(rAccess, bWhitespace); + bExtNamespace = false; // reset for future Export calls +} + +/// export a singular event and wirte <office:events> container +void XMLEventExport::ExportSingleEvent( + Sequence<PropertyValue>& rEventValues, + const OUString& rApiEventName, + sal_Bool bUseWhitespace ) +{ + // translate the name + NameMap::iterator aIter = aNameTranslationMap.find(rApiEventName); + if (aIter != aNameTranslationMap.end()) + { + const XMLEventName& rXmlName = aIter->second; + + // export the event ... + sal_Bool bStarted = sal_False; + ExportEvent( rEventValues, rXmlName, bUseWhitespace, bStarted ); + + // ... and close the container element (if necessary) + if (bStarted) + { + EndElement(bUseWhitespace); + } + } +#ifdef DBG_UTIL + else + { + // don't proceed further + ::rtl::OString aStr("Unknown event name:" ); + aStr += ::rtl::OUStringToOString( rApiEventName, RTL_TEXTENCODING_UTF8 ); + OSL_FAIL( aStr.getStr() ); + } +#endif +} + + +/// export a single event +void XMLEventExport::ExportEvent( + Sequence<PropertyValue>& rEventValues, + const XMLEventName& rXmlEventName, + sal_Bool bUseWhitespace, + sal_Bool& rExported ) +{ + // search for EventType value and then delegate to EventHandler + sal_Int32 nValues = rEventValues.getLength(); + const PropertyValue* pValues = rEventValues.getConstArray(); + + for(sal_Int32 nVal = 0; nVal < nValues; nVal++) + { + if (sEventType.equals(pValues[nVal].Name)) + { + // found! Now find handler and delegate + OUString sType; + pValues[nVal].Value >>= sType; + + if (aHandlerMap.count(sType)) + { + if (! rExported) + { + // OK, we have't yet exported the enclosing + // element. So we do that now. + rExported = sal_True; + StartElement(bUseWhitespace); + } + + OUString aEventQName( + rExport.GetNamespaceMap().GetQNameByKey( + rXmlEventName.m_nPrefix, rXmlEventName.m_aName ) ); + + // delegate to proper ExportEventHandler + aHandlerMap[sType]->Export(rExport, aEventQName, + rEventValues, bUseWhitespace); + } + else + { + if (! sType.equalsAsciiL("None", sizeof("None")-1)) + { + OSL_FAIL("unknown event type returned by API"); + // unknown type -> error (ignore) + } + // else: we ignore None fields + } + + // early out: we don't need to look for another type + break; + } + // else: we only care for EventType -> ignore + } +} + + +void XMLEventExport::StartElement(sal_Bool bWhitespace) +{ + if (bWhitespace) + { + rExport.IgnorableWhitespace(); + } + sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT + : XML_NAMESPACE_OFFICE; + rExport.StartElement( nNamespace, XML_EVENT_LISTENERS, + bWhitespace); +} + +void XMLEventExport::EndElement(sal_Bool bWhitespace) +{ + sal_uInt16 nNamespace = bExtNamespace ? XML_NAMESPACE_OFFICE_EXT + : XML_NAMESPACE_OFFICE; + rExport.EndElement(nNamespace, XML_EVENT_LISTENERS, bWhitespace); + if (bWhitespace) + { + rExport.IgnorableWhitespace(); + } +} + + +// implement aStandardEventTable (defined in xmlevent.hxx) +const XMLEventNameTranslation aStandardEventTable[] = +{ + { "OnSelect", XML_NAMESPACE_DOM, "select" }, // "on-select" + { "OnInsertStart", XML_NAMESPACE_OFFICE, "insert-start" }, // "on-insert-start" + { "OnInsertDone", XML_NAMESPACE_OFFICE, "insert-done" }, // "on-insert-done" + { "OnMailMerge", XML_NAMESPACE_OFFICE, "mail-merge" }, // "on-mail-merge" + { "OnAlphaCharInput", XML_NAMESPACE_OFFICE, "alpha-char-input" }, // "on-alpha-char-input" + { "OnNonAlphaCharInput", XML_NAMESPACE_OFFICE, "non-alpha-char-input" }, // "on-non-alpha-char-input" + { "OnResize", XML_NAMESPACE_DOM, "resize" }, // "on-resize" + { "OnMove", XML_NAMESPACE_OFFICE, "move" }, // "on-move" + { "OnPageCountChange", XML_NAMESPACE_OFFICE, "page-count-change" }, // "on-page-count-change" + { "OnMouseOver", XML_NAMESPACE_DOM, "mouseover" }, // "on-mouse-over" + { "OnClick", XML_NAMESPACE_DOM, "click" }, // "on-click" + { "OnMouseOut", XML_NAMESPACE_DOM, "mouseout" }, // "on-mouse-out" + { "OnLoadError", XML_NAMESPACE_OFFICE, "load-error" }, // "on-load-error" + { "OnLoadCancel", XML_NAMESPACE_OFFICE, "load-cancel" }, // "on-load-cancel" + { "OnLoadDone", XML_NAMESPACE_OFFICE, "load-done" }, // "on-load-done" + { "OnLoad", XML_NAMESPACE_DOM, "load" }, // "on-load" + { "OnUnload", XML_NAMESPACE_DOM, "unload" }, // "on-unload" + { "OnStartApp", XML_NAMESPACE_OFFICE, "start-app" }, // "on-start-app" + { "OnCloseApp", XML_NAMESPACE_OFFICE, "close-app" }, // "on-close-app" + { "OnNew", XML_NAMESPACE_OFFICE, "new" }, // "on-new" + { "OnSave", XML_NAMESPACE_OFFICE, "save" }, // "on-save" + { "OnSaveAs", XML_NAMESPACE_OFFICE, "save-as" }, // "on-save-as" + { "OnFocus", XML_NAMESPACE_DOM, "DOMFocusIn" }, // "on-focus" + { "OnUnfocus", XML_NAMESPACE_DOM, "DOMFocusOut" }, // "on-unfocus" + { "OnPrint", XML_NAMESPACE_OFFICE, "print" }, // "on-print" + { "OnError", XML_NAMESPACE_DOM, "error" }, // "on-error" + { "OnLoadFinished", XML_NAMESPACE_OFFICE, "load-finished" }, // "on-load-finished" + { "OnSaveFinished", XML_NAMESPACE_OFFICE, "save-finished" }, // "on-save-finished" + { "OnModifyChanged", XML_NAMESPACE_OFFICE, "modify-changed" }, // "on-modify-changed" + { "OnPrepareUnload", XML_NAMESPACE_OFFICE, "prepare-unload" }, // "on-prepare-unload" + { "OnNewMail", XML_NAMESPACE_OFFICE, "new-mail" }, // "on-new-mail" + { "OnToggleFullscreen", XML_NAMESPACE_OFFICE, "toggle-fullscreen" }, // "on-toggle-fullscreen" + { "OnSaveDone", XML_NAMESPACE_OFFICE, "save-done" }, // "on-save-done" + { "OnSaveAsDone", XML_NAMESPACE_OFFICE, "save-as-done" }, // "on-save-as-done" + { "OnCopyTo", XML_NAMESPACE_OFFICE, "copy-to" }, + { "OnCopyToDone", XML_NAMESPACE_OFFICE, "copy-to-done" }, + { "OnViewCreated", XML_NAMESPACE_OFFICE, "view-created" }, + { "OnPrepareViewClosing", XML_NAMESPACE_OFFICE, "prepare-view-closing" }, + { "OnViewClosed", XML_NAMESPACE_OFFICE, "view-close" }, + { "OnVisAreaChanged", XML_NAMESPACE_OFFICE, "visarea-changed" }, // "on-visarea-changed" + { "OnCreate", XML_NAMESPACE_OFFICE, "create" }, + { "OnSaveAsFailed", XML_NAMESPACE_OFFICE, "save-as-failed" }, + { "OnSaveFailed", XML_NAMESPACE_OFFICE, "save-failed" }, + { "OnCopyToFailed", XML_NAMESPACE_OFFICE, "copy-to-failed" }, + { "OnTitleChanged", XML_NAMESPACE_OFFICE, "title-changed" }, + { "OnModeChanged", XML_NAMESPACE_OFFICE, "mode-changed" }, + { "OnSaveTo", XML_NAMESPACE_OFFICE, "save-to" }, + { "OnSaveToDone", XML_NAMESPACE_OFFICE, "save-to-done" }, + { "OnSaveToFailed", XML_NAMESPACE_OFFICE, "save-to-failed" }, + { "OnSubComponentOpened", XML_NAMESPACE_OFFICE, "subcomponent-opened" }, + { "OnSubComponentClosed", XML_NAMESPACE_OFFICE, "subcomponent-closed" }, + { "OnStorageChanged", XML_NAMESPACE_OFFICE, "storage-changed" }, + { "OnMailMergeFinished", XML_NAMESPACE_OFFICE, "mail-merge-finished" }, + { "OnFieldMerge", XML_NAMESPACE_OFFICE, "field-merge" }, + { "OnFieldMergeFinished", XML_NAMESPACE_OFFICE, "field-merge-finished" }, + { "OnLayoutFinished", XML_NAMESPACE_OFFICE, "layout-finished" }, + { "OnDoubleClick", XML_NAMESPACE_OFFICE, "dblclick" }, + { "OnRightClick", XML_NAMESPACE_OFFICE, "contextmenu" }, + { "OnChange", XML_NAMESPACE_OFFICE, "content-changed" }, + { "OnCalculate", XML_NAMESPACE_OFFICE, "calculated" }, + + { NULL, 0, 0 } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |