diff options
Diffstat (limited to 'unoxml/source/events/eventdispatcher.cxx')
-rw-r--r-- | unoxml/source/events/eventdispatcher.cxx | 143 |
1 files changed, 94 insertions, 49 deletions
diff --git a/unoxml/source/events/eventdispatcher.cxx b/unoxml/source/events/eventdispatcher.cxx index 4b1c1548bf38..4b4cac807538 100644 --- a/unoxml/source/events/eventdispatcher.cxx +++ b/unoxml/source/events/eventdispatcher.cxx @@ -1,19 +1,46 @@ -#include "eventdispatcher.hxx" -#include "event.hxx" -#include "mutationevent.hxx" -#include "uievent.hxx" -#include "mouseevent.hxx" -#include "../dom/node.hxx" +/************************************************************************* + * + * 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. + * + ************************************************************************/ -namespace DOM { namespace events { +#include <eventdispatcher.hxx> + +#include <event.hxx> +#include <mutationevent.hxx> +#include <uievent.hxx> +#include <mouseevent.hxx> - TypeListenerMap CEventDispatcher::captureListeners; - TypeListenerMap CEventDispatcher::targetListeners; +#include "../dom/document.hxx" + + +namespace DOM { namespace events { void CEventDispatcher::addListener(xmlNodePtr pNode, OUString aType, const Reference<XEventListener>& aListener, sal_Bool bCapture) { - TypeListenerMap* pTMap = &targetListeners; - if (bCapture) pTMap = &captureListeners; + TypeListenerMap *const pTMap = (bCapture) + ? (& m_CaptureListeners) : (& m_TargetListeners); // get the multimap for the specified type ListenerMap *pMap = 0; @@ -31,8 +58,8 @@ namespace DOM { namespace events { void CEventDispatcher::removeListener(xmlNodePtr pNode, OUString aType, const Reference<XEventListener>& aListener, sal_Bool bCapture) { - TypeListenerMap *pTMap = &targetListeners; - if (bCapture) pTMap = &captureListeners; + TypeListenerMap *const pTMap = (bCapture) + ? (& m_CaptureListeners) : (& m_TargetListeners); // get the multimap for the specified type TypeListenerMap::const_iterator tIter = pTMap->find(aType); @@ -55,14 +82,14 @@ namespace DOM { namespace events { } } - void CEventDispatcher::callListeners(xmlNodePtr pNode, OUString aType, const Reference< XEvent >& xEvent, sal_Bool bCapture) + void CEventDispatcher::callListeners( + TypeListenerMap const& rTMap, + xmlNodePtr const pNode, + OUString aType, Reference< XEvent > const& xEvent) { - TypeListenerMap *pTMap = &targetListeners; - if (bCapture) pTMap = &captureListeners; - // get the multimap for the specified type - TypeListenerMap::const_iterator tIter = pTMap->find(aType); - if (tIter != pTMap->end()) { + TypeListenerMap::const_iterator tIter = rTMap.find(aType); + if (tIter != rTMap.end()) { ListenerMap *pMap = tIter->second; ListenerMap::const_iterator iter = pMap->lower_bound(pNode); ListenerMap::const_iterator ibound = pMap->upper_bound(pNode); @@ -74,12 +101,14 @@ namespace DOM { namespace events { } } - sal_Bool CEventDispatcher::dispatchEvent(xmlNodePtr aNodePtr, const Reference< XEvent >& aEvent) + bool CEventDispatcher::dispatchEvent( + DOM::CDocument & rDocument, ::osl::Mutex & rMutex, + xmlNodePtr const pNode, Reference<XNode> const& xNode, + Reference< XEvent > const& i_xEvent) const { CEvent *pEvent = 0; // pointer to internal event representation - Reference< XEvent > xEvent; // reference to the event being dispatched; - OUString aType = aEvent->getType(); + OUString const aType = i_xEvent->getType(); if (aType.compareToAscii("DOMSubtreeModified") == 0|| aType.compareToAscii("DOMNodeInserted") == 0|| aType.compareToAscii("DOMNodeRemoved") == 0|| @@ -88,7 +117,8 @@ namespace DOM { namespace events { aType.compareToAscii("DOMAttrModified") == 0|| aType.compareToAscii("DOMCharacterDataModified") == 0) { - Reference< XMutationEvent > aMEvent(aEvent, UNO_QUERY); + Reference< XMutationEvent > const aMEvent(i_xEvent, + UNO_QUERY_THROW); // dispatch a mutation event // we need to clone the event in order to have complete control // over the implementation @@ -104,7 +134,7 @@ namespace DOM { namespace events { aType.compareToAscii("DOMFocusOut") == 0|| aType.compareToAscii("DOMActivate") == 0) { - Reference< XUIEvent > aUIEvent(aEvent, UNO_QUERY); + Reference< XUIEvent > const aUIEvent(i_xEvent, UNO_QUERY_THROW); CUIEvent* pUIEvent = new CUIEvent; pUIEvent->initUIEvent(aType, aUIEvent->getBubbles(), aUIEvent->getCancelable(), @@ -118,7 +148,8 @@ namespace DOM { namespace events { aType.compareToAscii("mousemove") == 0|| aType.compareToAscii("mouseout") == 0) { - Reference< XMouseEvent > aMouseEvent(aEvent, UNO_QUERY); + Reference< XMouseEvent > const aMouseEvent(i_xEvent, + UNO_QUERY_THROW); CMouseEvent *pMouseEvent = new CMouseEvent; pMouseEvent->initMouseEvent(aType, aMouseEvent->getBubbles(), aMouseEvent->getCancelable(), @@ -134,23 +165,35 @@ namespace DOM { namespace events { { pEvent = new CEvent; pEvent->initEvent( - aType, aEvent->getBubbles(), aEvent->getCancelable()); + aType, i_xEvent->getBubbles(), i_xEvent->getCancelable()); } - pEvent->m_target = Reference< XEventTarget >(DOM::CNode::get(aNodePtr)); - pEvent->m_currentTarget = aEvent->getCurrentTarget(); - pEvent->m_time = aEvent->getTimeStamp(); + pEvent->m_target.set(xNode, UNO_QUERY_THROW); + pEvent->m_currentTarget = i_xEvent->getCurrentTarget(); + pEvent->m_time = i_xEvent->getTimeStamp(); // create the reference to the provate event implementation // that will be dispatched to the listeners - xEvent = Reference< XEvent >(pEvent); + Reference< XEvent > const xEvent(pEvent); // build the path from target node to the root - NodeVector captureVector; - xmlNodePtr cur = DOM::CNode::getNodePtr(Reference< XNode >(xEvent->getTarget(), UNO_QUERY_THROW)); - while (cur != NULL) + typedef std::vector< ::std::pair<Reference<XEventTarget>, xmlNodePtr> > + NodeVector_t; + NodeVector_t captureVector; + TypeListenerMap captureListeners; + TypeListenerMap targetListeners; { - captureVector.push_back(cur); - cur = cur->parent; + ::osl::MutexGuard g(rMutex); + + xmlNodePtr cur = pNode; + while (cur != NULL) + { + Reference< XEventTarget > const xRef( + rDocument.GetCNode(cur).get()); + captureVector.push_back(::std::make_pair(xRef, cur)); + cur = cur->parent; + } + captureListeners = m_CaptureListeners; + targetListeners = m_TargetListeners; } // the caputre vector now holds the node path from target to root @@ -158,36 +201,38 @@ namespace DOM { namespace events { // to target. after that, any target listeners have to be called // then bubbeling phase listeners are called in target to root // order - NodeVector::const_iterator inode; - // start at the root - inode = captureVector.end(); - inode--; - if (inode != captureVector.end()) + NodeVector_t::const_reverse_iterator rinode = + const_cast<NodeVector_t const&>(captureVector).rbegin(); + if (rinode != const_cast<NodeVector_t const&>(captureVector).rend()) { // capturing phase: pEvent->m_phase = PhaseType_CAPTURING_PHASE; - while (inode != captureVector.begin()) + while (rinode != + const_cast<NodeVector_t const&>(captureVector).rend()) { - //pEvent->m_currentTarget = *inode; - pEvent->m_currentTarget = Reference< XEventTarget >(DOM::CNode::get(*inode)); - callListeners(*inode, aType, xEvent, sal_True); + pEvent->m_currentTarget = rinode->first; + callListeners(captureListeners, rinode->second, aType, xEvent); if (pEvent->m_canceled) return sal_True; - inode--; + rinode++; } + NodeVector_t::const_iterator inode = captureVector.begin(); + // target phase pEvent->m_phase = PhaseType_AT_TARGET; - callListeners(*inode, aType, xEvent, sal_False); + pEvent->m_currentTarget = inode->first; + callListeners(targetListeners, inode->second, aType, xEvent); if (pEvent->m_canceled) return sal_True; // bubbeling phase inode++; - if (aEvent->getBubbles()) { + if (i_xEvent->getBubbles()) { pEvent->m_phase = PhaseType_BUBBLING_PHASE; while (inode != captureVector.end()) { - pEvent->m_currentTarget = Reference< XEventTarget >(DOM::CNode::get(*inode)); - callListeners(*inode, aType, xEvent, sal_False); + pEvent->m_currentTarget = inode->first; + callListeners(targetListeners, + inode->second, aType, xEvent); if (pEvent->m_canceled) return sal_True; inode++; } |