Update ooo320-m1
[ooovba.git] / slideshow / source / engine / eventmultiplexer.cxx
blobd62e74f2c04341c3089ebebe8b56632b2887c3ca
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventmultiplexer.cxx,v $
10 * $Revision: 1.16 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 // must be first
35 #include <canvas/debug.hxx>
36 #include <tools/diagnose_ex.h>
38 #include <rtl/ref.hxx>
39 #include <cppuhelper/compbase2.hxx>
40 #include <cppuhelper/basemutex.hxx>
42 #include <com/sun/star/awt/XMouseListener.hpp>
43 #include <com/sun/star/awt/XMouseMotionListener.hpp>
44 #include <com/sun/star/awt/SystemPointer.hpp>
45 #include <com/sun/star/awt/XWindow.hpp>
46 #include <com/sun/star/awt/MouseButton.hpp>
47 #include <com/sun/star/presentation/XSlideShowView.hpp>
49 #include <basegfx/matrix/b2dhommatrix.hxx>
50 #include <basegfx/numeric/ftools.hxx>
52 #include "tools.hxx"
53 #include "eventqueue.hxx"
54 #include "eventmultiplexer.hxx"
55 #include "listenercontainer.hxx"
56 #include "delayevent.hxx"
57 #include "unoview.hxx"
58 #include "unoviewcontainer.hxx"
60 #include <boost/shared_ptr.hpp>
61 #include <boost/weak_ptr.hpp>
62 #include <boost/function.hpp>
63 #include <boost/noncopyable.hpp>
64 #include <boost/bind.hpp>
66 #include <vector>
67 #include <hash_map>
68 #include <algorithm>
70 using namespace ::com::sun::star;
72 namespace boost
74 // add operator== for weak_ptr
75 template<typename T> bool operator==( weak_ptr<T> const& rLHS,
76 weak_ptr<T> const& rRHS )
78 return !(rLHS<rRHS) && !(rRHS<rLHS);
82 namespace slideshow {
83 namespace internal {
85 template <typename HandlerT>
86 class PrioritizedHandlerEntry
88 typedef boost::shared_ptr<HandlerT> HandlerSharedPtrT;
89 HandlerSharedPtrT mpHandler;
90 double mnPrio;
92 public:
93 PrioritizedHandlerEntry( HandlerSharedPtrT const& pHandler,
94 double nPrio ) :
95 mpHandler(pHandler),
96 mnPrio(nPrio)
99 HandlerSharedPtrT const& getHandler() const { return mpHandler; }
101 /// To sort according to priority
102 bool operator<( PrioritizedHandlerEntry const& rRHS ) const
104 // reversed order - high prioritized entries
105 // should be at the beginning of the queue
106 return mnPrio > rRHS.mnPrio;
109 /// To permit std::remove in removeHandler template
110 bool operator==( PrioritizedHandlerEntry const& rRHS ) const
112 // ignore prio, for removal, only the handler ptr matters
113 return mpHandler == rRHS.mpHandler;
117 template<typename T> inline T* get_pointer(PrioritizedHandlerEntry<T> const& handler)
119 return handler.getHandler().get();
124 ////////////////////////////////////////////////////////////////////////////
127 typedef cppu::WeakComponentImplHelper2<
128 awt::XMouseListener,
129 awt::XMouseMotionListener > Listener_UnoBase;
131 /** Listener class, to decouple UNO lifetime from EventMultiplexer
133 This class gets registered as the XMouse(Motion)Listener on the
134 XSlideViews, and passes on the events to the EventMultiplexer (via
135 EventQueue indirection, to force the events into the main thread)
137 class EventMultiplexerListener : private cppu::BaseMutex,
138 public Listener_UnoBase,
139 private ::boost::noncopyable
141 public:
142 EventMultiplexerListener( EventQueue& rEventQueue,
143 EventMultiplexerImpl& rEventMultiplexer ) :
144 Listener_UnoBase( m_aMutex ),
145 mpEventQueue( &rEventQueue ),
146 mpEventMultiplexer( &rEventMultiplexer )
150 // WeakComponentImplHelperBase::disposing
151 virtual void SAL_CALL disposing();
153 private:
154 virtual void SAL_CALL disposing( const lang::EventObject& Source )
155 throw (uno::RuntimeException);
157 // XMouseListener implementation
158 virtual void SAL_CALL mousePressed( const awt::MouseEvent& e )
159 throw (uno::RuntimeException);
160 virtual void SAL_CALL mouseReleased( const awt::MouseEvent& e )
161 throw (uno::RuntimeException);
162 virtual void SAL_CALL mouseEntered( const awt::MouseEvent& e )
163 throw (uno::RuntimeException);
164 virtual void SAL_CALL mouseExited( const awt::MouseEvent& e )
165 throw (uno::RuntimeException);
167 // XMouseMotionListener implementation
168 virtual void SAL_CALL mouseDragged( const awt::MouseEvent& e )
169 throw (uno::RuntimeException);
170 virtual void SAL_CALL mouseMoved( const awt::MouseEvent& e )
171 throw (uno::RuntimeException);
174 EventQueue* mpEventQueue;
175 EventMultiplexerImpl* mpEventMultiplexer;
179 ////////////////////////////////////////////////////////////////////////////
182 struct EventMultiplexerImpl
184 EventMultiplexerImpl( EventQueue& rEventQueue,
185 UnoViewContainer const& rViewContainer ) :
186 mrEventQueue(rEventQueue),
187 mrViewContainer(rViewContainer),
188 mxListener( new EventMultiplexerListener(rEventQueue,
189 *this) ),
190 maNextEffectHandlers(),
191 maSlideStartHandlers(),
192 maSlideEndHandlers(),
193 maAnimationStartHandlers(),
194 maAnimationEndHandlers(),
195 maSlideAnimationsEndHandlers(),
196 maAudioStoppedHandlers(),
197 maCommandStopAudioHandlers(),
198 maPauseHandlers(),
199 maViewHandlers(),
200 maViewRepaintHandlers(),
201 maShapeListenerHandlers(),
202 maUserPaintEventHandlers(),
203 maShapeCursorHandlers(),
204 maMouseClickHandlers(),
205 maMouseDoubleClickHandlers(),
206 maMouseMoveHandlers(),
207 maHyperlinkHandlers(),
208 mnTimeout(0.0),
209 mpTickEvent(),
210 mbIsAutoMode(false)
213 ~EventMultiplexerImpl()
215 if( mxListener.is() )
216 mxListener->dispose();
219 /// Remove all handlers
220 void clear();
222 // actual handler callbacks (get called from the UNO interface
223 // listeners via event queue)
224 void mousePressed( const awt::MouseEvent& e );
225 void mouseReleased( const awt::MouseEvent& e );
226 void mouseDragged( const awt::MouseEvent& e );
227 void mouseMoved( const awt::MouseEvent& e );
229 bool isMouseListenerRegistered() const;
231 typedef ThreadUnsafeListenerContainer<
232 PrioritizedHandlerEntry<EventHandler>,
233 std::vector<
234 PrioritizedHandlerEntry<EventHandler> > > ImplNextEffectHandlers;
235 typedef PrioritizedHandlerEntry<MouseEventHandler> ImplMouseHandlerEntry;
236 typedef ThreadUnsafeListenerContainer<
237 ImplMouseHandlerEntry,
238 std::vector<ImplMouseHandlerEntry> > ImplMouseHandlers;
239 typedef ThreadUnsafeListenerContainer<
240 EventHandlerSharedPtr,
241 std::vector<EventHandlerSharedPtr> > ImplEventHandlers;
242 typedef ThreadUnsafeListenerContainer<
243 AnimationEventHandlerSharedPtr,
244 std::vector<AnimationEventHandlerSharedPtr> > ImplAnimationHandlers;
245 typedef ThreadUnsafeListenerContainer<
246 PauseEventHandlerSharedPtr,
247 std::vector<PauseEventHandlerSharedPtr> > ImplPauseHandlers;
248 typedef ThreadUnsafeListenerContainer<
249 ViewEventHandlerWeakPtr,
250 std::vector<ViewEventHandlerWeakPtr> > ImplViewHandlers;
251 typedef ThreadUnsafeListenerContainer<
252 ViewRepaintHandlerSharedPtr,
253 std::vector<ViewRepaintHandlerSharedPtr> > ImplRepaintHandlers;
254 typedef ThreadUnsafeListenerContainer<
255 ShapeListenerEventHandlerSharedPtr,
256 std::vector<ShapeListenerEventHandlerSharedPtr> > ImplShapeListenerHandlers;
257 typedef ThreadUnsafeListenerContainer<
258 UserPaintEventHandlerSharedPtr,
259 std::vector<UserPaintEventHandlerSharedPtr> > ImplUserPaintEventHandlers;
260 typedef ThreadUnsafeListenerContainer<
261 ShapeCursorEventHandlerSharedPtr,
262 std::vector<ShapeCursorEventHandlerSharedPtr> > ImplShapeCursorHandlers;
263 typedef ThreadUnsafeListenerContainer<
264 PrioritizedHandlerEntry<HyperlinkHandler>,
265 std::vector<
266 PrioritizedHandlerEntry<HyperlinkHandler> > > ImplHyperLinkHandlers;
268 template <typename XSlideShowViewFunc>
269 void forEachView( XSlideShowViewFunc pViewMethod );
271 UnoViewSharedPtr findUnoView(const uno::Reference<
272 presentation::XSlideShowView>& xView) const;
274 template< typename RegisterFunction >
275 void addMouseHandler( ImplMouseHandlers& rHandlerContainer,
276 const MouseEventHandlerSharedPtr& rHandler,
277 double nPriority,
278 RegisterFunction pRegisterListener );
280 bool notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
281 AnimationNodeSharedPtr const& rNode );
283 bool notifyMouseHandlers(
284 const ImplMouseHandlers& rQueue,
285 bool (MouseEventHandler::*pHandlerMethod)(
286 const awt::MouseEvent& ),
287 const awt::MouseEvent& e );
289 bool notifyNextEffect();
291 /// Called for automatic nextEffect
292 void tick();
294 /// Schedules a tick event
295 void scheduleTick();
297 /// Schedules tick events, if mbIsAutoMode is true
298 void handleTicks();
301 EventQueue& mrEventQueue;
302 UnoViewContainer const& mrViewContainer;
303 ::rtl::Reference<
304 EventMultiplexerListener> mxListener;
306 ImplNextEffectHandlers maNextEffectHandlers;
307 ImplEventHandlers maSlideStartHandlers;
308 ImplEventHandlers maSlideEndHandlers;
309 ImplAnimationHandlers maAnimationStartHandlers;
310 ImplAnimationHandlers maAnimationEndHandlers;
311 ImplEventHandlers maSlideAnimationsEndHandlers;
312 ImplAnimationHandlers maAudioStoppedHandlers;
313 ImplAnimationHandlers maCommandStopAudioHandlers;
314 ImplPauseHandlers maPauseHandlers;
315 ImplViewHandlers maViewHandlers;
316 ImplRepaintHandlers maViewRepaintHandlers;
317 ImplShapeListenerHandlers maShapeListenerHandlers;
318 ImplUserPaintEventHandlers maUserPaintEventHandlers;
319 ImplShapeCursorHandlers maShapeCursorHandlers;
320 ImplMouseHandlers maMouseClickHandlers;
321 ImplMouseHandlers maMouseDoubleClickHandlers;
322 ImplMouseHandlers maMouseMoveHandlers;
323 ImplHyperLinkHandlers maHyperlinkHandlers;
325 /// automatic next effect mode timeout
326 double mnTimeout;
328 /** Holds ptr to optional tick event weakly
330 When event queue is cleansed, the next
331 setAutomaticMode(true) call is then able to
332 regenerate the event.
334 ::boost::weak_ptr< Event > mpTickEvent;
335 bool mbIsAutoMode;
339 ///////////////////////////////////////////////////////////////////////////
342 void SAL_CALL EventMultiplexerListener::disposing()
344 osl::MutexGuard const guard( m_aMutex );
345 mpEventQueue = NULL;
346 mpEventMultiplexer = NULL;
349 void SAL_CALL EventMultiplexerListener::disposing(
350 const lang::EventObject& /*rSource*/ ) throw (uno::RuntimeException)
352 // there's no real point in acting on this message - after all,
353 // the event sources are the XSlideShowViews, which must be
354 // explicitely removed from the slideshow via
355 // XSlideShow::removeView(). thus, if a XSlideShowView has
356 // properly removed itself from the slideshow, it will not be
357 // found here. and if it hasn't, there'll be other references at
358 // other places within the slideshow, anyway...
361 void SAL_CALL EventMultiplexerListener::mousePressed(
362 const awt::MouseEvent& e ) throw (uno::RuntimeException)
364 osl::MutexGuard const guard( m_aMutex );
366 // notify mouse press. Don't call handlers directly, this
367 // might not be the main thread!
368 if( mpEventQueue )
369 mpEventQueue->addEvent(
370 makeEvent( boost::bind( &EventMultiplexerImpl::mousePressed,
371 mpEventMultiplexer,
372 e ) ) );
375 void SAL_CALL EventMultiplexerListener::mouseReleased(
376 const awt::MouseEvent& e ) throw (uno::RuntimeException)
378 osl::MutexGuard const guard( m_aMutex );
380 // notify mouse release. Don't call handlers directly,
381 // this might not be the main thread!
382 if( mpEventQueue )
383 mpEventQueue->addEvent(
384 makeEvent( boost::bind( &EventMultiplexerImpl::mouseReleased,
385 mpEventMultiplexer,
386 e ) ) );
389 void SAL_CALL EventMultiplexerListener::mouseEntered(
390 const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException)
392 // not used here
395 void SAL_CALL EventMultiplexerListener::mouseExited(
396 const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException)
398 // not used here
401 // XMouseMotionListener implementation
402 void SAL_CALL EventMultiplexerListener::mouseDragged(
403 const awt::MouseEvent& e ) throw (uno::RuntimeException)
405 osl::MutexGuard const guard( m_aMutex );
407 // notify mouse drag. Don't call handlers directly, this
408 // might not be the main thread!
409 if( mpEventQueue )
410 mpEventQueue->addEvent(
411 makeEvent( boost::bind( &EventMultiplexerImpl::mouseDragged,
412 mpEventMultiplexer,
413 e )) );
416 void SAL_CALL EventMultiplexerListener::mouseMoved(
417 const awt::MouseEvent& e ) throw (uno::RuntimeException)
419 osl::MutexGuard const guard( m_aMutex );
421 // notify mouse move. Don't call handlers directly, this
422 // might not be the main thread!
423 if( mpEventQueue )
424 mpEventQueue->addEvent(
425 makeEvent( boost::bind( &EventMultiplexerImpl::mouseMoved,
426 mpEventMultiplexer,
427 e )) );
431 ///////////////////////////////////////////////////////////////////////////
434 bool EventMultiplexerImpl::notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
435 AnimationNodeSharedPtr const& rNode )
437 return rContainer.applyAll(
438 boost::bind( &AnimationEventHandler::handleAnimationEvent,
439 _1, boost::cref(rNode) ) );
442 template <typename XSlideShowViewFunc>
443 void EventMultiplexerImpl::forEachView( XSlideShowViewFunc pViewMethod )
445 if( pViewMethod )
447 // (un)register mouse listener on all views
448 for( UnoViewVector::const_iterator aIter( mrViewContainer.begin() ),
449 aEnd( mrViewContainer.end() ); aIter != aEnd; ++aIter )
451 uno::Reference<presentation::XSlideShowView> xView ((*aIter)->getUnoView());
452 if (xView.is())
454 (xView.get()->*pViewMethod)( mxListener.get() );
456 else
458 OSL_ASSERT(xView.is());
464 UnoViewSharedPtr EventMultiplexerImpl::findUnoView(
465 const uno::Reference<presentation::XSlideShowView>& xView) const
467 // find view from which the change originated
468 UnoViewVector::const_iterator aIter;
469 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
470 if( (aIter=std::find_if( mrViewContainer.begin(),
471 aEnd,
472 boost::bind(
473 std::equal_to<uno::Reference<presentation::XSlideShowView> >(),
474 boost::cref( xView ),
475 boost::bind( &UnoView::getUnoView, _1 )))) == aEnd )
477 OSL_ENSURE(false, "EventMultiplexer::findUnoView(): unexpected message source" );
478 return UnoViewSharedPtr();
481 return *aIter;
484 template< typename RegisterFunction >
485 void EventMultiplexerImpl::addMouseHandler(
486 ImplMouseHandlers& rHandlerContainer,
487 const MouseEventHandlerSharedPtr& rHandler,
488 double nPriority,
489 RegisterFunction pRegisterListener )
491 ENSURE_OR_THROW(
492 rHandler,
493 "EventMultiplexer::addMouseHandler(): Invalid handler" );
495 // register mouse listener on all views
496 forEachView( pRegisterListener );
498 // add into sorted container:
499 rHandlerContainer.addSorted(
500 typename ImplMouseHandlers::container_type::value_type(
501 rHandler,
502 nPriority ));
505 bool EventMultiplexerImpl::isMouseListenerRegistered() const
507 return !(maMouseClickHandlers.isEmpty() &&
508 maMouseDoubleClickHandlers.isEmpty());
511 void EventMultiplexerImpl::tick()
513 if( !mbIsAutoMode )
514 return; // this event is just a left-over, ignore
516 notifyNextEffect();
518 if( !maNextEffectHandlers.isEmpty() )
520 // still handlers left, schedule next timeout
521 // event. Will also set mbIsTickEventOn back to true
522 scheduleTick();
526 void EventMultiplexerImpl::scheduleTick()
528 EventSharedPtr pEvent(
529 makeDelay( boost::bind( &EventMultiplexerImpl::tick,
530 this ),
531 mnTimeout ));
533 // store weak reference to generated event, to notice when
534 // the event queue gets cleansed (we then have to
535 // regenerate the tick event!)
536 mpTickEvent = pEvent;
538 // enabled auto mode: simply schedule a timeout event,
539 // which will eventually call our tick() method
540 mrEventQueue.addEventForNextRound( pEvent );
543 void EventMultiplexerImpl::handleTicks()
545 if( !mbIsAutoMode )
546 return; // nothing to do, don't need no ticks
548 EventSharedPtr pTickEvent( mpTickEvent.lock() );
549 if( pTickEvent )
550 return; // nothing to do, there's already a tick
551 // pending
553 // schedule initial tick (which reschedules itself
554 // after that, all by itself)
555 scheduleTick();
559 void EventMultiplexerImpl::clear()
561 // deregister from all views.
562 if( isMouseListenerRegistered() )
564 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
565 aEnd=mrViewContainer.end();
566 aIter!=aEnd;
567 ++aIter )
569 if( (*aIter)->getUnoView().is() )
570 (*aIter)->getUnoView()->removeMouseListener( mxListener.get() );
574 if( !maMouseMoveHandlers.isEmpty() )
576 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
577 aEnd=mrViewContainer.end();
578 aIter!=aEnd;
579 ++aIter )
581 if( (*aIter)->getUnoView().is() )
582 (*aIter)->getUnoView()->removeMouseMotionListener( mxListener.get() );
586 // clear all handlers (releases all references)
587 maNextEffectHandlers.clear();
588 maSlideStartHandlers.clear();
589 maSlideEndHandlers.clear();
590 maAnimationStartHandlers.clear();
591 maAnimationEndHandlers.clear();
592 maSlideAnimationsEndHandlers.clear();
593 maAudioStoppedHandlers.clear();
594 maCommandStopAudioHandlers.clear();
595 maPauseHandlers.clear();
596 maViewHandlers.clear();
597 maViewRepaintHandlers.clear();
598 maMouseClickHandlers.clear();
599 maMouseDoubleClickHandlers.clear();
600 maMouseMoveHandlers.clear();
601 maHyperlinkHandlers.clear();
602 mpTickEvent.reset();
605 // XMouseListener implementation
606 bool EventMultiplexerImpl::notifyMouseHandlers(
607 const ImplMouseHandlers& rQueue,
608 bool (MouseEventHandler::*pHandlerMethod)( const awt::MouseEvent& ),
609 const awt::MouseEvent& e )
611 uno::Reference<presentation::XSlideShowView> xView(
612 e.Source, uno::UNO_QUERY );
614 ENSURE_OR_RETURN( xView.is(), "EventMultiplexer::notifyHandlers(): "
615 "event source is not an XSlideShowView" );
617 // find corresponding view (to map mouse position into user
618 // coordinate space)
619 UnoViewVector::const_iterator aIter;
620 const UnoViewVector::const_iterator aBegin( mrViewContainer.begin() );
621 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
622 if( (aIter=::std::find_if(
623 aBegin, aEnd,
624 boost::bind( std::equal_to< uno::Reference<
625 presentation::XSlideShowView > >(),
626 boost::cref( xView ),
627 boost::bind( &UnoView::getUnoView, _1 ) ) ) ) == aEnd)
629 ENSURE_OR_RETURN(
630 false, "EventMultiplexer::notifyHandlers(): "
631 "event source not found under registered views" );
634 // convert mouse position to user coordinate space
635 ::basegfx::B2DPoint aPosition( e.X, e.Y );
636 ::basegfx::B2DHomMatrix aMatrix( (*aIter)->getTransformation() );
637 if( !aMatrix.invert() )
638 ENSURE_OR_THROW( false, "EventMultiplexer::notifyHandlers():"
639 " view matrix singular" );
640 aPosition *= aMatrix;
642 awt::MouseEvent aEvent( e );
643 aEvent.X = ::basegfx::fround( aPosition.getX() );
644 aEvent.Y = ::basegfx::fround( aPosition.getY() );
646 // fire event on handlers, try in order of precedence. If
647 // one high-priority handler rejects the event
648 // (i.e. returns false), try next handler.
649 return rQueue.apply(
650 boost::bind(
651 pHandlerMethod,
652 boost::bind(
653 &ImplMouseHandlers::container_type::value_type::getHandler,
654 _1 ),
655 aEvent ));
658 void EventMultiplexerImpl::mousePressed( const awt::MouseEvent& e )
660 // fire double-click events for every second click
661 sal_Int32 nCurrClickCount = e.ClickCount;
662 while( nCurrClickCount > 1 &&
663 notifyMouseHandlers( maMouseDoubleClickHandlers,
664 &MouseEventHandler::handleMousePressed,
665 e ))
667 nCurrClickCount -= 2;
670 // fire single-click events for all remaining clicks
671 while( nCurrClickCount > 0 &&
672 notifyMouseHandlers( maMouseClickHandlers,
673 &MouseEventHandler::handleMousePressed,
674 e ))
676 --nCurrClickCount;
680 void EventMultiplexerImpl::mouseReleased( const awt::MouseEvent& e )
682 // fire double-click events for every second click
683 sal_Int32 nCurrClickCount = e.ClickCount;
684 while( nCurrClickCount > 1 &&
685 notifyMouseHandlers( maMouseDoubleClickHandlers,
686 &MouseEventHandler::handleMouseReleased,
687 e ))
689 nCurrClickCount -= 2;
692 // fire single-click events for all remaining clicks
693 while( nCurrClickCount > 0 &&
694 notifyMouseHandlers( maMouseClickHandlers,
695 &MouseEventHandler::handleMouseReleased,
696 e ))
698 --nCurrClickCount;
702 void EventMultiplexerImpl::mouseDragged( const awt::MouseEvent& e )
704 notifyMouseHandlers( maMouseMoveHandlers,
705 &MouseEventHandler::handleMouseDragged,
706 e );
709 void EventMultiplexerImpl::mouseMoved( const awt::MouseEvent& e )
711 notifyMouseHandlers( maMouseMoveHandlers,
712 &MouseEventHandler::handleMouseMoved,
713 e );
716 bool EventMultiplexerImpl::notifyNextEffect()
718 // fire event on handlers, try in order of precedence. If one
719 // high-priority handler rejects the event (i.e. returns false),
720 // try next handler.
721 return maNextEffectHandlers.apply(
722 boost::bind(
723 &EventHandler::handleEvent,
724 boost::bind(
725 &ImplNextEffectHandlers::container_type::value_type::getHandler,
726 _1 )) );
729 //////////////////////////////////////////////////////////////////////////
732 EventMultiplexer::EventMultiplexer( EventQueue& rEventQueue,
733 UnoViewContainer const& rViewContainer ) :
734 mpImpl( new EventMultiplexerImpl(rEventQueue, rViewContainer) )
738 EventMultiplexer::~EventMultiplexer()
740 // outline because of EventMultiplexerImpl's incomplete type
743 void EventMultiplexer::clear()
745 mpImpl->clear();
748 void EventMultiplexer::setAutomaticMode( bool bIsAuto )
750 if( bIsAuto == mpImpl->mbIsAutoMode )
751 return; // no change, nothing to do
753 mpImpl->mbIsAutoMode = bIsAuto;
755 mpImpl->handleTicks();
758 bool EventMultiplexer::getAutomaticMode() const
760 return mpImpl->mbIsAutoMode;
763 void EventMultiplexer::setAutomaticTimeout( double nTimeout )
765 mpImpl->mnTimeout = nTimeout;
768 double EventMultiplexer::getAutomaticTimeout() const
770 return mpImpl->mnTimeout;
773 void EventMultiplexer::addNextEffectHandler(
774 EventHandlerSharedPtr const& rHandler,
775 double nPriority )
777 mpImpl->maNextEffectHandlers.addSorted(
778 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
779 rHandler,
780 nPriority) );
782 // Enable tick events, if not done already
783 mpImpl->handleTicks();
786 void EventMultiplexer::removeNextEffectHandler(
787 const EventHandlerSharedPtr& rHandler )
789 mpImpl->maNextEffectHandlers.remove(
790 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
791 rHandler,
792 0.0) );
795 void EventMultiplexer::addSlideStartHandler(
796 const EventHandlerSharedPtr& rHandler )
798 mpImpl->maSlideStartHandlers.add( rHandler );
801 void EventMultiplexer::removeSlideStartHandler(
802 const EventHandlerSharedPtr& rHandler )
804 mpImpl->maSlideStartHandlers.remove( rHandler );
807 void EventMultiplexer::addSlideEndHandler(
808 const EventHandlerSharedPtr& rHandler )
810 mpImpl->maSlideEndHandlers.add( rHandler );
813 void EventMultiplexer::removeSlideEndHandler(
814 const EventHandlerSharedPtr& rHandler )
816 mpImpl->maSlideEndHandlers.remove( rHandler );
819 void EventMultiplexer::addAnimationStartHandler(
820 const AnimationEventHandlerSharedPtr& rHandler )
822 mpImpl->maAnimationStartHandlers.add( rHandler );
825 void EventMultiplexer::removeAnimationStartHandler(
826 const AnimationEventHandlerSharedPtr& rHandler )
828 mpImpl->maAnimationStartHandlers.remove( rHandler );
831 void EventMultiplexer::addAnimationEndHandler(
832 const AnimationEventHandlerSharedPtr& rHandler )
834 mpImpl->maAnimationEndHandlers.add( rHandler );
837 void EventMultiplexer::removeAnimationEndHandler(
838 const AnimationEventHandlerSharedPtr& rHandler )
840 mpImpl->maAnimationEndHandlers.remove( rHandler );
843 void EventMultiplexer::addSlideAnimationsEndHandler(
844 const EventHandlerSharedPtr& rHandler )
846 mpImpl->maSlideAnimationsEndHandlers.add( rHandler );
849 void EventMultiplexer::removeSlideAnimationsEndHandler(
850 const EventHandlerSharedPtr& rHandler )
852 mpImpl->maSlideAnimationsEndHandlers.remove( rHandler );
855 void EventMultiplexer::addAudioStoppedHandler(
856 const AnimationEventHandlerSharedPtr& rHandler )
858 mpImpl->maAudioStoppedHandlers.add( rHandler );
861 void EventMultiplexer::removeAudioStoppedHandler(
862 const AnimationEventHandlerSharedPtr& rHandler )
864 mpImpl->maAudioStoppedHandlers.remove( rHandler );
867 void EventMultiplexer::addCommandStopAudioHandler(
868 const AnimationEventHandlerSharedPtr& rHandler )
870 mpImpl->maCommandStopAudioHandlers.add( rHandler );
873 void EventMultiplexer::removeCommandStopAudioHandler(
874 const AnimationEventHandlerSharedPtr& rHandler )
876 mpImpl->maCommandStopAudioHandlers.remove( rHandler );
879 void EventMultiplexer::addPauseHandler(
880 const PauseEventHandlerSharedPtr& rHandler )
882 mpImpl->maPauseHandlers.add( rHandler );
885 void EventMultiplexer::removePauseHandler(
886 const PauseEventHandlerSharedPtr& rHandler )
888 mpImpl->maPauseHandlers.remove( rHandler );
891 void EventMultiplexer::addViewHandler(
892 const ViewEventHandlerWeakPtr& rHandler )
894 mpImpl->maViewHandlers.add( rHandler );
897 void EventMultiplexer::removeViewHandler( const ViewEventHandlerWeakPtr& rHandler )
899 mpImpl->maViewHandlers.remove( rHandler );
902 void EventMultiplexer::addViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
904 mpImpl->maViewRepaintHandlers.add( rHandler );
907 void EventMultiplexer::removeViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
909 mpImpl->maViewRepaintHandlers.remove( rHandler );
912 void EventMultiplexer::addShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
914 mpImpl->maShapeListenerHandlers.add( rHandler );
917 void EventMultiplexer::removeShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
919 mpImpl->maShapeListenerHandlers.remove( rHandler );
922 void EventMultiplexer::addUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler )
924 mpImpl->maUserPaintEventHandlers.add( rHandler );
927 void EventMultiplexer::removeUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler )
929 mpImpl->maUserPaintEventHandlers.remove( rHandler );
932 void EventMultiplexer::addShapeCursorHandler( const ShapeCursorEventHandlerSharedPtr& rHandler )
934 mpImpl->maShapeCursorHandlers.add( rHandler );
937 void EventMultiplexer::removeShapeCursorHandler( const ShapeCursorEventHandlerSharedPtr& rHandler )
939 mpImpl->maShapeCursorHandlers.remove( rHandler );
942 void EventMultiplexer::addClickHandler(
943 const MouseEventHandlerSharedPtr& rHandler,
944 double nPriority )
946 mpImpl->addMouseHandler(
947 mpImpl->maMouseClickHandlers,
948 rHandler,
949 nPriority,
950 mpImpl->isMouseListenerRegistered()
951 ? NULL
952 : &presentation::XSlideShowView::addMouseListener );
955 void EventMultiplexer::removeClickHandler(
956 const MouseEventHandlerSharedPtr& rHandler )
958 mpImpl->maMouseClickHandlers.remove(
959 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
960 rHandler,
961 0.0) );
963 if( !mpImpl->isMouseListenerRegistered() )
964 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
967 void EventMultiplexer::addDoubleClickHandler(
968 const MouseEventHandlerSharedPtr& rHandler,
969 double nPriority )
971 mpImpl->addMouseHandler(
972 mpImpl->maMouseDoubleClickHandlers,
973 rHandler,
974 nPriority,
975 mpImpl->isMouseListenerRegistered()
976 ? NULL
977 : &presentation::XSlideShowView::addMouseListener );
980 void EventMultiplexer::removeDoubleClickHandler(
981 const MouseEventHandlerSharedPtr& rHandler )
983 mpImpl->maMouseDoubleClickHandlers.remove(
984 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
985 rHandler,
986 0.0) );
988 if( !mpImpl->isMouseListenerRegistered() )
989 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
992 void EventMultiplexer::addMouseMoveHandler(
993 const MouseEventHandlerSharedPtr& rHandler,
994 double nPriority )
996 mpImpl->addMouseHandler(
997 mpImpl->maMouseMoveHandlers,
998 rHandler,
999 nPriority,
1000 mpImpl->maMouseMoveHandlers.isEmpty()
1001 ? &presentation::XSlideShowView::addMouseMotionListener
1002 : NULL );
1005 void EventMultiplexer::removeMouseMoveHandler(
1006 const MouseEventHandlerSharedPtr& rHandler )
1008 mpImpl->maMouseMoveHandlers.remove(
1009 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
1010 rHandler,
1011 0.0) );
1013 if( mpImpl->maMouseMoveHandlers.isEmpty() )
1014 mpImpl->forEachView(
1015 &presentation::XSlideShowView::removeMouseMotionListener );
1018 void EventMultiplexer::addHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler,
1019 double nPriority )
1021 mpImpl->maHyperlinkHandlers.addSorted(
1022 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
1023 rHandler,
1024 nPriority) );
1027 void EventMultiplexer::removeHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler )
1029 mpImpl->maHyperlinkHandlers.remove(
1030 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
1031 rHandler,
1032 0.0) );
1035 bool EventMultiplexer::notifyShapeListenerAdded(
1036 const uno::Reference<presentation::XShapeEventListener>& xListener,
1037 const uno::Reference<drawing::XShape>& xShape )
1039 return mpImpl->maShapeListenerHandlers.applyAll(
1040 boost::bind(&ShapeListenerEventHandler::listenerAdded,
1042 boost::cref(xListener),
1043 boost::cref(xShape)) );
1046 bool EventMultiplexer::notifyShapeListenerRemoved(
1047 const uno::Reference<presentation::XShapeEventListener>& xListener,
1048 const uno::Reference<drawing::XShape>& xShape )
1050 return mpImpl->maShapeListenerHandlers.applyAll(
1051 boost::bind(&ShapeListenerEventHandler::listenerRemoved,
1053 boost::cref(xListener),
1054 boost::cref(xShape)) );
1057 bool EventMultiplexer::notifyShapeCursorChange(
1058 const uno::Reference<drawing::XShape>& xShape,
1059 sal_Int16 nPointerShape )
1061 return mpImpl->maShapeCursorHandlers.applyAll(
1062 boost::bind(&ShapeCursorEventHandler::cursorChanged,
1064 boost::cref(xShape),
1065 nPointerShape));
1068 bool EventMultiplexer::notifyUserPaintColor( RGBColor const& rUserColor )
1070 return mpImpl->maUserPaintEventHandlers.applyAll(
1071 boost::bind(&UserPaintEventHandler::colorChanged,
1073 boost::cref(rUserColor)));
1076 bool EventMultiplexer::notifyUserPaintStrokeWidth( double rUserStrokeWidth )
1078 return mpImpl->maUserPaintEventHandlers.applyAll(
1079 boost::bind(&UserPaintEventHandler::widthChanged,
1081 rUserStrokeWidth));
1084 bool EventMultiplexer::notifyUserPaintDisabled()
1086 return mpImpl->maUserPaintEventHandlers.applyAll(
1087 boost::mem_fn(&UserPaintEventHandler::disable));
1090 bool EventMultiplexer::notifyNextEffect()
1092 return mpImpl->notifyNextEffect();
1095 bool EventMultiplexer::notifySlideStartEvent()
1097 return mpImpl->maSlideStartHandlers.applyAll(
1098 boost::mem_fn(&EventHandler::handleEvent) );
1101 bool EventMultiplexer::notifySlideEndEvent()
1103 return mpImpl->maSlideEndHandlers.applyAll(
1104 boost::mem_fn(&EventHandler::handleEvent) );
1107 bool EventMultiplexer::notifyAnimationStart(
1108 const AnimationNodeSharedPtr& rNode )
1110 return mpImpl->notifyAllAnimationHandlers( mpImpl->maAnimationStartHandlers,
1111 rNode );
1114 bool EventMultiplexer::notifyAnimationEnd(
1115 const AnimationNodeSharedPtr& rNode )
1117 return mpImpl->notifyAllAnimationHandlers( mpImpl->maAnimationEndHandlers,
1118 rNode );
1121 bool EventMultiplexer::notifySlideAnimationsEnd()
1123 return mpImpl->maSlideAnimationsEndHandlers.applyAll(
1124 boost::mem_fn(&EventHandler::handleEvent));
1127 bool EventMultiplexer::notifyAudioStopped(
1128 const AnimationNodeSharedPtr& rNode )
1130 return mpImpl->notifyAllAnimationHandlers(
1131 mpImpl->maAudioStoppedHandlers,
1132 rNode );
1135 bool EventMultiplexer::notifyCommandStopAudio(
1136 const AnimationNodeSharedPtr& rNode )
1138 return mpImpl->notifyAllAnimationHandlers(
1139 mpImpl->maCommandStopAudioHandlers,
1140 rNode );
1143 bool EventMultiplexer::notifyPauseMode( bool bPauseShow )
1145 return mpImpl->maPauseHandlers.applyAll(
1146 boost::bind( &PauseEventHandler::handlePause,
1147 _1, bPauseShow ));
1150 bool EventMultiplexer::notifyViewAdded( const UnoViewSharedPtr& rView )
1152 ENSURE_OR_THROW( rView, "EventMultiplexer::notifyViewAdded(): Invalid view");
1154 // register event listener
1155 uno::Reference<presentation::XSlideShowView> const rUnoView(
1156 rView->getUnoView() );
1158 if( mpImpl->isMouseListenerRegistered() )
1159 rUnoView->addMouseListener(
1160 mpImpl->mxListener.get() );
1162 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1163 rUnoView->addMouseMotionListener(
1164 mpImpl->mxListener.get() );
1166 return mpImpl->maViewHandlers.applyAll(
1167 boost::bind( &ViewEventHandler::viewAdded,
1169 boost::cref(rView) ));
1172 bool EventMultiplexer::notifyViewRemoved( const UnoViewSharedPtr& rView )
1174 ENSURE_OR_THROW( rView,
1175 "EventMultiplexer::removeView(): Invalid view" );
1177 // revoke event listeners
1178 uno::Reference<presentation::XSlideShowView> const rUnoView(
1179 rView->getUnoView() );
1181 if( mpImpl->isMouseListenerRegistered() )
1182 rUnoView->removeMouseListener(
1183 mpImpl->mxListener.get() );
1185 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1186 rUnoView->removeMouseMotionListener(
1187 mpImpl->mxListener.get() );
1189 return mpImpl->maViewHandlers.applyAll(
1190 boost::bind( &ViewEventHandler::viewRemoved,
1192 boost::cref(rView) ));
1195 bool EventMultiplexer::notifyViewChanged( const UnoViewSharedPtr& rView )
1197 return mpImpl->maViewHandlers.applyAll(
1198 boost::bind( &ViewEventHandler::viewChanged,
1200 boost::cref(rView) ));
1203 bool EventMultiplexer::notifyViewChanged( const uno::Reference<presentation::XSlideShowView>& xView )
1205 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1207 if( !pView )
1208 return false; // view not registered here
1210 return notifyViewChanged( pView );
1213 bool EventMultiplexer::notifyViewsChanged()
1215 return mpImpl->maViewHandlers.applyAll(
1216 boost::mem_fn( &ViewEventHandler::viewsChanged ));
1219 bool EventMultiplexer::notifyViewClobbered(
1220 const uno::Reference<presentation::XSlideShowView>& xView )
1222 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1224 if( !pView )
1225 return false; // view not registered here
1227 return mpImpl->maViewRepaintHandlers.applyAll(
1228 boost::bind( &ViewRepaintHandler::viewClobbered,
1230 boost::cref(pView) ));
1233 bool EventMultiplexer::notifyHyperlinkClicked(
1234 rtl::OUString const& hyperLink )
1236 return mpImpl->maHyperlinkHandlers.apply(
1237 boost::bind(&HyperlinkHandler::handleHyperlink,
1239 boost::cref(hyperLink)) );
1242 bool EventMultiplexer::notifySlideTransitionStarted()
1244 return true;
1247 } // namespace internal
1248 } // namespace presentation