1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include <eventdispatcher.hxx> 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include <event.hxx> 31*cdf0e10cSrcweir #include <mutationevent.hxx> 32*cdf0e10cSrcweir #include <uievent.hxx> 33*cdf0e10cSrcweir #include <mouseevent.hxx> 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include "../dom/document.hxx" 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir namespace DOM { namespace events { 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir void CEventDispatcher::addListener(xmlNodePtr pNode, OUString aType, const Reference<XEventListener>& aListener, sal_Bool bCapture) 41*cdf0e10cSrcweir { 42*cdf0e10cSrcweir TypeListenerMap *const pTMap = (bCapture) 43*cdf0e10cSrcweir ? (& m_CaptureListeners) : (& m_TargetListeners); 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir // get the multimap for the specified type 46*cdf0e10cSrcweir ListenerMap *pMap = 0; 47*cdf0e10cSrcweir TypeListenerMap::const_iterator tIter = pTMap->find(aType); 48*cdf0e10cSrcweir if (tIter == pTMap->end()) { 49*cdf0e10cSrcweir // the map has to be created 50*cdf0e10cSrcweir pMap = new ListenerMap(); 51*cdf0e10cSrcweir pTMap->insert(TypeListenerMap::value_type(aType, pMap)); 52*cdf0e10cSrcweir } else { 53*cdf0e10cSrcweir pMap = tIter->second; 54*cdf0e10cSrcweir } 55*cdf0e10cSrcweir if (pMap !=0) 56*cdf0e10cSrcweir pMap->insert(ListenerMap::value_type(pNode, aListener)); 57*cdf0e10cSrcweir } 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir void CEventDispatcher::removeListener(xmlNodePtr pNode, OUString aType, const Reference<XEventListener>& aListener, sal_Bool bCapture) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir TypeListenerMap *const pTMap = (bCapture) 62*cdf0e10cSrcweir ? (& m_CaptureListeners) : (& m_TargetListeners); 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir // get the multimap for the specified type 65*cdf0e10cSrcweir TypeListenerMap::const_iterator tIter = pTMap->find(aType); 66*cdf0e10cSrcweir if (tIter != pTMap->end()) { 67*cdf0e10cSrcweir ListenerMap *pMap = tIter->second; 68*cdf0e10cSrcweir // find listeners of specied type for specified node 69*cdf0e10cSrcweir ListenerMap::iterator iter = pMap->find(pNode); 70*cdf0e10cSrcweir while (iter != pMap->end() && iter->first == pNode) 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir // erase all references to specified listener 73*cdf0e10cSrcweir if ((iter->second).is() && iter->second == aListener) 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir ListenerMap::iterator tmp_iter = iter; 76*cdf0e10cSrcweir iter++; 77*cdf0e10cSrcweir pMap->erase(tmp_iter); 78*cdf0e10cSrcweir } 79*cdf0e10cSrcweir else 80*cdf0e10cSrcweir iter++; 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir } 83*cdf0e10cSrcweir } 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir void CEventDispatcher::callListeners( 86*cdf0e10cSrcweir TypeListenerMap const& rTMap, 87*cdf0e10cSrcweir xmlNodePtr const pNode, 88*cdf0e10cSrcweir OUString aType, Reference< XEvent > const& xEvent) 89*cdf0e10cSrcweir { 90*cdf0e10cSrcweir // get the multimap for the specified type 91*cdf0e10cSrcweir TypeListenerMap::const_iterator tIter = rTMap.find(aType); 92*cdf0e10cSrcweir if (tIter != rTMap.end()) { 93*cdf0e10cSrcweir ListenerMap *pMap = tIter->second; 94*cdf0e10cSrcweir ListenerMap::const_iterator iter = pMap->lower_bound(pNode); 95*cdf0e10cSrcweir ListenerMap::const_iterator ibound = pMap->upper_bound(pNode); 96*cdf0e10cSrcweir for( ; iter != ibound; iter++ ) 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir if((iter->second).is()) 99*cdf0e10cSrcweir (iter->second)->handleEvent(xEvent); 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir } 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir bool CEventDispatcher::dispatchEvent( 105*cdf0e10cSrcweir DOM::CDocument & rDocument, ::osl::Mutex & rMutex, 106*cdf0e10cSrcweir xmlNodePtr const pNode, Reference<XNode> const& xNode, 107*cdf0e10cSrcweir Reference< XEvent > const& i_xEvent) const 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir CEvent *pEvent = 0; // pointer to internal event representation 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir OUString const aType = i_xEvent->getType(); 112*cdf0e10cSrcweir if (aType.compareToAscii("DOMSubtreeModified") == 0|| 113*cdf0e10cSrcweir aType.compareToAscii("DOMNodeInserted") == 0|| 114*cdf0e10cSrcweir aType.compareToAscii("DOMNodeRemoved") == 0|| 115*cdf0e10cSrcweir aType.compareToAscii("DOMNodeRemovedFromDocument") == 0|| 116*cdf0e10cSrcweir aType.compareToAscii("DOMNodeInsertedIntoDocument") == 0|| 117*cdf0e10cSrcweir aType.compareToAscii("DOMAttrModified") == 0|| 118*cdf0e10cSrcweir aType.compareToAscii("DOMCharacterDataModified") == 0) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir Reference< XMutationEvent > const aMEvent(i_xEvent, 121*cdf0e10cSrcweir UNO_QUERY_THROW); 122*cdf0e10cSrcweir // dispatch a mutation event 123*cdf0e10cSrcweir // we need to clone the event in order to have complete control 124*cdf0e10cSrcweir // over the implementation 125*cdf0e10cSrcweir CMutationEvent* pMEvent = new CMutationEvent; 126*cdf0e10cSrcweir pMEvent->initMutationEvent( 127*cdf0e10cSrcweir aType, aMEvent->getBubbles(), aMEvent->getCancelable(), 128*cdf0e10cSrcweir aMEvent->getRelatedNode(), aMEvent->getPrevValue(), 129*cdf0e10cSrcweir aMEvent->getNewValue(), aMEvent->getAttrName(), 130*cdf0e10cSrcweir aMEvent->getAttrChange()); 131*cdf0e10cSrcweir pEvent = pMEvent; 132*cdf0e10cSrcweir } else if ( // UIEvent 133*cdf0e10cSrcweir aType.compareToAscii("DOMFocusIn") == 0|| 134*cdf0e10cSrcweir aType.compareToAscii("DOMFocusOut") == 0|| 135*cdf0e10cSrcweir aType.compareToAscii("DOMActivate") == 0) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir Reference< XUIEvent > const aUIEvent(i_xEvent, UNO_QUERY_THROW); 138*cdf0e10cSrcweir CUIEvent* pUIEvent = new CUIEvent; 139*cdf0e10cSrcweir pUIEvent->initUIEvent(aType, 140*cdf0e10cSrcweir aUIEvent->getBubbles(), aUIEvent->getCancelable(), 141*cdf0e10cSrcweir aUIEvent->getView(), aUIEvent->getDetail()); 142*cdf0e10cSrcweir pEvent = pUIEvent; 143*cdf0e10cSrcweir } else if ( // MouseEvent 144*cdf0e10cSrcweir aType.compareToAscii("click") == 0|| 145*cdf0e10cSrcweir aType.compareToAscii("mousedown") == 0|| 146*cdf0e10cSrcweir aType.compareToAscii("mouseup") == 0|| 147*cdf0e10cSrcweir aType.compareToAscii("mouseover") == 0|| 148*cdf0e10cSrcweir aType.compareToAscii("mousemove") == 0|| 149*cdf0e10cSrcweir aType.compareToAscii("mouseout") == 0) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir Reference< XMouseEvent > const aMouseEvent(i_xEvent, 152*cdf0e10cSrcweir UNO_QUERY_THROW); 153*cdf0e10cSrcweir CMouseEvent *pMouseEvent = new CMouseEvent; 154*cdf0e10cSrcweir pMouseEvent->initMouseEvent(aType, 155*cdf0e10cSrcweir aMouseEvent->getBubbles(), aMouseEvent->getCancelable(), 156*cdf0e10cSrcweir aMouseEvent->getView(), aMouseEvent->getDetail(), 157*cdf0e10cSrcweir aMouseEvent->getScreenX(), aMouseEvent->getScreenY(), 158*cdf0e10cSrcweir aMouseEvent->getClientX(), aMouseEvent->getClientY(), 159*cdf0e10cSrcweir aMouseEvent->getCtrlKey(), aMouseEvent->getAltKey(), 160*cdf0e10cSrcweir aMouseEvent->getShiftKey(), aMouseEvent->getMetaKey(), 161*cdf0e10cSrcweir aMouseEvent->getButton(), aMouseEvent->getRelatedTarget()); 162*cdf0e10cSrcweir pEvent = pMouseEvent; 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir else // generic event 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir pEvent = new CEvent; 167*cdf0e10cSrcweir pEvent->initEvent( 168*cdf0e10cSrcweir aType, i_xEvent->getBubbles(), i_xEvent->getCancelable()); 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir pEvent->m_target.set(xNode, UNO_QUERY_THROW); 171*cdf0e10cSrcweir pEvent->m_currentTarget = i_xEvent->getCurrentTarget(); 172*cdf0e10cSrcweir pEvent->m_time = i_xEvent->getTimeStamp(); 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir // create the reference to the provate event implementation 175*cdf0e10cSrcweir // that will be dispatched to the listeners 176*cdf0e10cSrcweir Reference< XEvent > const xEvent(pEvent); 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir // build the path from target node to the root 179*cdf0e10cSrcweir typedef std::vector< ::std::pair<Reference<XEventTarget>, xmlNodePtr> > 180*cdf0e10cSrcweir NodeVector_t; 181*cdf0e10cSrcweir NodeVector_t captureVector; 182*cdf0e10cSrcweir TypeListenerMap captureListeners; 183*cdf0e10cSrcweir TypeListenerMap targetListeners; 184*cdf0e10cSrcweir { 185*cdf0e10cSrcweir ::osl::MutexGuard g(rMutex); 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir xmlNodePtr cur = pNode; 188*cdf0e10cSrcweir while (cur != NULL) 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir Reference< XEventTarget > const xRef( 191*cdf0e10cSrcweir rDocument.GetCNode(cur).get()); 192*cdf0e10cSrcweir captureVector.push_back(::std::make_pair(xRef, cur)); 193*cdf0e10cSrcweir cur = cur->parent; 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir captureListeners = m_CaptureListeners; 196*cdf0e10cSrcweir targetListeners = m_TargetListeners; 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir // the caputre vector now holds the node path from target to root 200*cdf0e10cSrcweir // first we must search for capture listernes in order root to 201*cdf0e10cSrcweir // to target. after that, any target listeners have to be called 202*cdf0e10cSrcweir // then bubbeling phase listeners are called in target to root 203*cdf0e10cSrcweir // order 204*cdf0e10cSrcweir // start at the root 205*cdf0e10cSrcweir NodeVector_t::const_reverse_iterator rinode = 206*cdf0e10cSrcweir const_cast<NodeVector_t const&>(captureVector).rbegin(); 207*cdf0e10cSrcweir if (rinode != const_cast<NodeVector_t const&>(captureVector).rend()) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir // capturing phase: 210*cdf0e10cSrcweir pEvent->m_phase = PhaseType_CAPTURING_PHASE; 211*cdf0e10cSrcweir while (rinode != 212*cdf0e10cSrcweir const_cast<NodeVector_t const&>(captureVector).rend()) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir pEvent->m_currentTarget = rinode->first; 215*cdf0e10cSrcweir callListeners(captureListeners, rinode->second, aType, xEvent); 216*cdf0e10cSrcweir if (pEvent->m_canceled) return sal_True; 217*cdf0e10cSrcweir rinode++; 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir NodeVector_t::const_iterator inode = captureVector.begin(); 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir // target phase 223*cdf0e10cSrcweir pEvent->m_phase = PhaseType_AT_TARGET; 224*cdf0e10cSrcweir pEvent->m_currentTarget = inode->first; 225*cdf0e10cSrcweir callListeners(targetListeners, inode->second, aType, xEvent); 226*cdf0e10cSrcweir if (pEvent->m_canceled) return sal_True; 227*cdf0e10cSrcweir // bubbeling phase 228*cdf0e10cSrcweir inode++; 229*cdf0e10cSrcweir if (i_xEvent->getBubbles()) { 230*cdf0e10cSrcweir pEvent->m_phase = PhaseType_BUBBLING_PHASE; 231*cdf0e10cSrcweir while (inode != captureVector.end()) 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir pEvent->m_currentTarget = inode->first; 234*cdf0e10cSrcweir callListeners(targetListeners, 235*cdf0e10cSrcweir inode->second, aType, xEvent); 236*cdf0e10cSrcweir if (pEvent->m_canceled) return sal_True; 237*cdf0e10cSrcweir inode++; 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir return sal_True; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir }} 244