bump product version to 4.1.6.2
[LibreOffice.git] / slideshow / source / engine / eventmultiplexer.cxx
blob67625937317bcb803253a34cfdb0b9d615dd53a2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 // must be first
22 #include <canvas/debug.hxx>
23 #include <tools/diagnose_ex.h>
25 #include <rtl/ref.hxx>
26 #include <cppuhelper/compbase2.hxx>
27 #include <cppuhelper/basemutex.hxx>
29 #include <com/sun/star/awt/XMouseListener.hpp>
30 #include <com/sun/star/awt/XMouseMotionListener.hpp>
31 #include <com/sun/star/awt/SystemPointer.hpp>
32 #include <com/sun/star/awt/XWindow.hpp>
33 #include <com/sun/star/awt/MouseButton.hpp>
34 #include <com/sun/star/presentation/XSlideShowView.hpp>
36 #include <basegfx/matrix/b2dhommatrix.hxx>
37 #include <basegfx/numeric/ftools.hxx>
39 #include "tools.hxx"
40 #include "eventqueue.hxx"
41 #include "eventmultiplexer.hxx"
42 #include "listenercontainer.hxx"
43 #include "delayevent.hxx"
44 #include "unoview.hxx"
45 #include "unoviewcontainer.hxx"
47 #include <boost/shared_ptr.hpp>
48 #include <boost/weak_ptr.hpp>
49 #include <boost/function.hpp>
50 #include <boost/noncopyable.hpp>
51 #include <boost/bind.hpp>
53 #include <vector>
54 #include <boost/unordered_map.hpp>
55 #include <algorithm>
57 using namespace ::com::sun::star;
59 namespace boost
61 // add operator== for weak_ptr
62 template<typename T> bool operator==( weak_ptr<T> const& rLHS,
63 weak_ptr<T> const& rRHS )
65 return !(rLHS<rRHS) && !(rRHS<rLHS);
69 namespace slideshow {
70 namespace internal {
72 template <typename HandlerT>
73 class PrioritizedHandlerEntry
75 typedef boost::shared_ptr<HandlerT> HandlerSharedPtrT;
76 HandlerSharedPtrT mpHandler;
77 double mnPrio;
79 public:
80 PrioritizedHandlerEntry( HandlerSharedPtrT const& pHandler,
81 double nPrio ) :
82 mpHandler(pHandler),
83 mnPrio(nPrio)
86 HandlerSharedPtrT const& getHandler() const { return mpHandler; }
88 /// To sort according to priority
89 bool operator<( PrioritizedHandlerEntry const& rRHS ) const
91 // reversed order - high prioritized entries
92 // should be at the beginning of the queue
93 return mnPrio > rRHS.mnPrio;
96 /// To permit std::remove in removeHandler template
97 bool operator==( PrioritizedHandlerEntry const& rRHS ) const
99 // ignore prio, for removal, only the handler ptr matters
100 return mpHandler == rRHS.mpHandler;
104 template<typename T> inline T* get_pointer(PrioritizedHandlerEntry<T> const& handler)
106 return handler.getHandler().get();
111 ////////////////////////////////////////////////////////////////////////////
114 typedef cppu::WeakComponentImplHelper2<
115 awt::XMouseListener,
116 awt::XMouseMotionListener > Listener_UnoBase;
118 /** Listener class, to decouple UNO lifetime from EventMultiplexer
120 This class gets registered as the XMouse(Motion)Listener on the
121 XSlideViews, and passes on the events to the EventMultiplexer (via
122 EventQueue indirection, to force the events into the main thread)
124 class EventMultiplexerListener : private cppu::BaseMutex,
125 public Listener_UnoBase,
126 private ::boost::noncopyable
128 public:
129 EventMultiplexerListener( EventQueue& rEventQueue,
130 EventMultiplexerImpl& rEventMultiplexer ) :
131 Listener_UnoBase( m_aMutex ),
132 mpEventQueue( &rEventQueue ),
133 mpEventMultiplexer( &rEventMultiplexer )
137 // WeakComponentImplHelperBase::disposing
138 virtual void SAL_CALL disposing();
140 private:
141 virtual void SAL_CALL disposing( const lang::EventObject& Source )
142 throw (uno::RuntimeException);
144 // XMouseListener implementation
145 virtual void SAL_CALL mousePressed( const awt::MouseEvent& e )
146 throw (uno::RuntimeException);
147 virtual void SAL_CALL mouseReleased( const awt::MouseEvent& e )
148 throw (uno::RuntimeException);
149 virtual void SAL_CALL mouseEntered( const awt::MouseEvent& e )
150 throw (uno::RuntimeException);
151 virtual void SAL_CALL mouseExited( const awt::MouseEvent& e )
152 throw (uno::RuntimeException);
154 // XMouseMotionListener implementation
155 virtual void SAL_CALL mouseDragged( const awt::MouseEvent& e )
156 throw (uno::RuntimeException);
157 virtual void SAL_CALL mouseMoved( const awt::MouseEvent& e )
158 throw (uno::RuntimeException);
161 EventQueue* mpEventQueue;
162 EventMultiplexerImpl* mpEventMultiplexer;
166 ////////////////////////////////////////////////////////////////////////////
169 struct EventMultiplexerImpl
171 EventMultiplexerImpl( EventQueue& rEventQueue,
172 UnoViewContainer const& rViewContainer ) :
173 mrEventQueue(rEventQueue),
174 mrViewContainer(rViewContainer),
175 mxListener( new EventMultiplexerListener(rEventQueue,
176 *this) ),
177 maNextEffectHandlers(),
178 maSlideStartHandlers(),
179 maSlideEndHandlers(),
180 maAnimationStartHandlers(),
181 maAnimationEndHandlers(),
182 maSlideAnimationsEndHandlers(),
183 maAudioStoppedHandlers(),
184 maCommandStopAudioHandlers(),
185 maPauseHandlers(),
186 maViewHandlers(),
187 maViewRepaintHandlers(),
188 maShapeListenerHandlers(),
189 maUserPaintEventHandlers(),
190 maShapeCursorHandlers(),
191 maMouseClickHandlers(),
192 maMouseDoubleClickHandlers(),
193 maMouseMoveHandlers(),
194 maHyperlinkHandlers(),
195 mnTimeout(0.0),
196 mpTickEvent(),
197 mbIsAutoMode(false)
200 ~EventMultiplexerImpl()
202 if( mxListener.is() )
203 mxListener->dispose();
206 /// Remove all handlers
207 void clear();
209 // actual handler callbacks (get called from the UNO interface
210 // listeners via event queue)
211 void mousePressed( const awt::MouseEvent& e );
212 void mouseReleased( const awt::MouseEvent& e );
213 void mouseDragged( const awt::MouseEvent& e );
214 void mouseMoved( const awt::MouseEvent& e );
216 bool isMouseListenerRegistered() const;
218 typedef ThreadUnsafeListenerContainer<
219 PrioritizedHandlerEntry<EventHandler>,
220 std::vector<
221 PrioritizedHandlerEntry<EventHandler> > > ImplNextEffectHandlers;
222 typedef PrioritizedHandlerEntry<MouseEventHandler> ImplMouseHandlerEntry;
223 typedef ThreadUnsafeListenerContainer<
224 ImplMouseHandlerEntry,
225 std::vector<ImplMouseHandlerEntry> > ImplMouseHandlers;
226 typedef ThreadUnsafeListenerContainer<
227 EventHandlerSharedPtr,
228 std::vector<EventHandlerSharedPtr> > ImplEventHandlers;
229 typedef ThreadUnsafeListenerContainer<
230 AnimationEventHandlerSharedPtr,
231 std::vector<AnimationEventHandlerSharedPtr> > ImplAnimationHandlers;
232 typedef ThreadUnsafeListenerContainer<
233 PauseEventHandlerSharedPtr,
234 std::vector<PauseEventHandlerSharedPtr> > ImplPauseHandlers;
235 typedef ThreadUnsafeListenerContainer<
236 ViewEventHandlerWeakPtr,
237 std::vector<ViewEventHandlerWeakPtr> > ImplViewHandlers;
238 typedef ThreadUnsafeListenerContainer<
239 ViewRepaintHandlerSharedPtr,
240 std::vector<ViewRepaintHandlerSharedPtr> > ImplRepaintHandlers;
241 typedef ThreadUnsafeListenerContainer<
242 ShapeListenerEventHandlerSharedPtr,
243 std::vector<ShapeListenerEventHandlerSharedPtr> > ImplShapeListenerHandlers;
244 typedef ThreadUnsafeListenerContainer<
245 UserPaintEventHandlerSharedPtr,
246 std::vector<UserPaintEventHandlerSharedPtr> > ImplUserPaintEventHandlers;
247 typedef ThreadUnsafeListenerContainer<
248 ShapeCursorEventHandlerSharedPtr,
249 std::vector<ShapeCursorEventHandlerSharedPtr> > ImplShapeCursorHandlers;
250 typedef ThreadUnsafeListenerContainer<
251 PrioritizedHandlerEntry<HyperlinkHandler>,
252 std::vector<PrioritizedHandlerEntry<HyperlinkHandler> > > ImplHyperLinkHandlers;
254 template <typename XSlideShowViewFunc>
255 void forEachView( XSlideShowViewFunc pViewMethod );
257 UnoViewSharedPtr findUnoView(const uno::Reference<
258 presentation::XSlideShowView>& xView) const;
260 template< typename RegisterFunction >
261 void addMouseHandler( ImplMouseHandlers& rHandlerContainer,
262 const MouseEventHandlerSharedPtr& rHandler,
263 double nPriority,
264 RegisterFunction pRegisterListener );
266 bool notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
267 AnimationNodeSharedPtr const& rNode );
269 bool notifyMouseHandlers(
270 const ImplMouseHandlers& rQueue,
271 bool (MouseEventHandler::*pHandlerMethod)(
272 const awt::MouseEvent& ),
273 const awt::MouseEvent& e );
275 bool notifyNextEffect();
277 /// Called for automatic nextEffect
278 void tick();
280 /// Schedules a tick event
281 void scheduleTick();
283 /// Schedules tick events, if mbIsAutoMode is true
284 void handleTicks();
287 EventQueue& mrEventQueue;
288 UnoViewContainer const& mrViewContainer;
289 ::rtl::Reference<
290 EventMultiplexerListener> mxListener;
292 ImplNextEffectHandlers maNextEffectHandlers;
293 ImplEventHandlers maSlideStartHandlers;
294 ImplEventHandlers maSlideEndHandlers;
295 ImplAnimationHandlers maAnimationStartHandlers;
296 ImplAnimationHandlers maAnimationEndHandlers;
297 ImplEventHandlers maSlideAnimationsEndHandlers;
298 ImplAnimationHandlers maAudioStoppedHandlers;
299 ImplAnimationHandlers maCommandStopAudioHandlers;
300 ImplPauseHandlers maPauseHandlers;
301 ImplViewHandlers maViewHandlers;
302 ImplRepaintHandlers maViewRepaintHandlers;
303 ImplShapeListenerHandlers maShapeListenerHandlers;
304 ImplUserPaintEventHandlers maUserPaintEventHandlers;
305 ImplShapeCursorHandlers maShapeCursorHandlers;
306 ImplMouseHandlers maMouseClickHandlers;
307 ImplMouseHandlers maMouseDoubleClickHandlers;
308 ImplMouseHandlers maMouseMoveHandlers;
309 ImplHyperLinkHandlers maHyperlinkHandlers;
311 /// automatic next effect mode timeout
312 double mnTimeout;
314 /** Holds ptr to optional tick event weakly
316 When event queue is cleansed, the next
317 setAutomaticMode(true) call is then able to
318 regenerate the event.
320 ::boost::weak_ptr< Event > mpTickEvent;
321 bool mbIsAutoMode;
325 ///////////////////////////////////////////////////////////////////////////
328 void SAL_CALL EventMultiplexerListener::disposing()
330 osl::MutexGuard const guard( m_aMutex );
331 mpEventQueue = NULL;
332 mpEventMultiplexer = NULL;
335 void SAL_CALL EventMultiplexerListener::disposing(
336 const lang::EventObject& /*rSource*/ ) throw (uno::RuntimeException)
338 // there's no real point in acting on this message - after all,
339 // the event sources are the XSlideShowViews, which must be
340 // explicitly removed from the slideshow via
341 // XSlideShow::removeView(). thus, if a XSlideShowView has
342 // properly removed itself from the slideshow, it will not be
343 // found here. and if it hasn't, there'll be other references at
344 // other places within the slideshow, anyway...
347 void SAL_CALL EventMultiplexerListener::mousePressed(
348 const awt::MouseEvent& e ) throw (uno::RuntimeException)
350 osl::MutexGuard const guard( m_aMutex );
352 // notify mouse press. Don't call handlers directly, this
353 // might not be the main thread!
354 if( mpEventQueue )
355 mpEventQueue->addEvent(
356 makeEvent( boost::bind( &EventMultiplexerImpl::mousePressed,
357 mpEventMultiplexer,
358 e ),
359 "EventMultiplexerImpl::mousePressed") );
362 void SAL_CALL EventMultiplexerListener::mouseReleased(
363 const awt::MouseEvent& e ) throw (uno::RuntimeException)
365 osl::MutexGuard const guard( m_aMutex );
367 // notify mouse release. Don't call handlers directly,
368 // this might not be the main thread!
369 if( mpEventQueue )
370 mpEventQueue->addEvent(
371 makeEvent( boost::bind( &EventMultiplexerImpl::mouseReleased,
372 mpEventMultiplexer,
373 e ),
374 "EventMultiplexerImpl::mouseReleased") );
377 void SAL_CALL EventMultiplexerListener::mouseEntered(
378 const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException)
380 // not used here
383 void SAL_CALL EventMultiplexerListener::mouseExited(
384 const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException)
386 // not used here
389 // XMouseMotionListener implementation
390 void SAL_CALL EventMultiplexerListener::mouseDragged(
391 const awt::MouseEvent& e ) throw (uno::RuntimeException)
393 osl::MutexGuard const guard( m_aMutex );
395 // notify mouse drag. Don't call handlers directly, this
396 // might not be the main thread!
397 if( mpEventQueue )
398 mpEventQueue->addEvent(
399 makeEvent( boost::bind( &EventMultiplexerImpl::mouseDragged,
400 mpEventMultiplexer,
401 e ),
402 "EventMultiplexerImpl::mouseDragged") );
405 void SAL_CALL EventMultiplexerListener::mouseMoved(
406 const awt::MouseEvent& e ) throw (uno::RuntimeException)
408 osl::MutexGuard const guard( m_aMutex );
410 // notify mouse move. Don't call handlers directly, this
411 // might not be the main thread!
412 if( mpEventQueue )
413 mpEventQueue->addEvent(
414 makeEvent( boost::bind( &EventMultiplexerImpl::mouseMoved,
415 mpEventMultiplexer,
416 e ),
417 "EventMultiplexerImpl::mouseMoved") );
421 ///////////////////////////////////////////////////////////////////////////
424 bool EventMultiplexerImpl::notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
425 AnimationNodeSharedPtr const& rNode )
427 return rContainer.applyAll(
428 boost::bind( &AnimationEventHandler::handleAnimationEvent,
429 _1, boost::cref(rNode) ) );
432 template <typename XSlideShowViewFunc>
433 void EventMultiplexerImpl::forEachView( XSlideShowViewFunc pViewMethod )
435 if( pViewMethod )
437 // (un)register mouse listener on all views
438 for( UnoViewVector::const_iterator aIter( mrViewContainer.begin() ),
439 aEnd( mrViewContainer.end() ); aIter != aEnd; ++aIter )
441 uno::Reference<presentation::XSlideShowView> xView ((*aIter)->getUnoView());
442 if (xView.is())
444 (xView.get()->*pViewMethod)( mxListener.get() );
446 else
448 OSL_ASSERT(xView.is());
454 UnoViewSharedPtr EventMultiplexerImpl::findUnoView(
455 const uno::Reference<presentation::XSlideShowView>& xView) const
457 // find view from which the change originated
458 UnoViewVector::const_iterator aIter;
459 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
460 if( (aIter=std::find_if( mrViewContainer.begin(),
461 aEnd,
462 boost::bind(
463 std::equal_to<uno::Reference<presentation::XSlideShowView> >(),
464 boost::cref( xView ),
465 boost::bind( &UnoView::getUnoView, _1 )))) == aEnd )
467 OSL_FAIL("EventMultiplexer::findUnoView(): unexpected message source" );
468 return UnoViewSharedPtr();
471 return *aIter;
474 template< typename RegisterFunction >
475 void EventMultiplexerImpl::addMouseHandler(
476 ImplMouseHandlers& rHandlerContainer,
477 const MouseEventHandlerSharedPtr& rHandler,
478 double nPriority,
479 RegisterFunction pRegisterListener )
481 ENSURE_OR_THROW(
482 rHandler,
483 "EventMultiplexer::addMouseHandler(): Invalid handler" );
485 // register mouse listener on all views
486 forEachView( pRegisterListener );
488 // add into sorted container:
489 rHandlerContainer.addSorted(
490 typename ImplMouseHandlers::container_type::value_type(
491 rHandler,
492 nPriority ));
495 bool EventMultiplexerImpl::isMouseListenerRegistered() const
497 return !(maMouseClickHandlers.isEmpty() &&
498 maMouseDoubleClickHandlers.isEmpty());
501 void EventMultiplexerImpl::tick()
503 if( !mbIsAutoMode )
504 return; // this event is just a left-over, ignore
506 notifyNextEffect();
508 if( !maNextEffectHandlers.isEmpty() )
510 // still handlers left, schedule next timeout
511 // event. Will also set mbIsTickEventOn back to true
512 scheduleTick();
516 void EventMultiplexerImpl::scheduleTick()
518 EventSharedPtr pEvent(
519 makeDelay( boost::bind( &EventMultiplexerImpl::tick,
520 this ),
521 mnTimeout,
522 "EventMultiplexerImpl::tick with delay"));
524 // store weak reference to generated event, to notice when
525 // the event queue gets cleansed (we then have to
526 // regenerate the tick event!)
527 mpTickEvent = pEvent;
529 // enabled auto mode: simply schedule a timeout event,
530 // which will eventually call our tick() method
531 mrEventQueue.addEventForNextRound( pEvent );
534 void EventMultiplexerImpl::handleTicks()
536 if( !mbIsAutoMode )
537 return; // nothing to do, don't need no ticks
539 EventSharedPtr pTickEvent( mpTickEvent.lock() );
540 if( pTickEvent )
541 return; // nothing to do, there's already a tick
542 // pending
544 // schedule initial tick (which reschedules itself
545 // after that, all by itself)
546 scheduleTick();
550 void EventMultiplexerImpl::clear()
552 // deregister from all views.
553 if( isMouseListenerRegistered() )
555 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
556 aEnd=mrViewContainer.end();
557 aIter!=aEnd;
558 ++aIter )
560 if( (*aIter)->getUnoView().is() )
561 (*aIter)->getUnoView()->removeMouseListener( mxListener.get() );
565 if( !maMouseMoveHandlers.isEmpty() )
567 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
568 aEnd=mrViewContainer.end();
569 aIter!=aEnd;
570 ++aIter )
572 if( (*aIter)->getUnoView().is() )
573 (*aIter)->getUnoView()->removeMouseMotionListener( mxListener.get() );
577 // clear all handlers (releases all references)
578 maNextEffectHandlers.clear();
579 maSlideStartHandlers.clear();
580 maSlideEndHandlers.clear();
581 maAnimationStartHandlers.clear();
582 maAnimationEndHandlers.clear();
583 maSlideAnimationsEndHandlers.clear();
584 maAudioStoppedHandlers.clear();
585 maCommandStopAudioHandlers.clear();
586 maPauseHandlers.clear();
587 maViewHandlers.clear();
588 maViewRepaintHandlers.clear();
589 maMouseClickHandlers.clear();
590 maMouseDoubleClickHandlers.clear();
591 maMouseMoveHandlers.clear();
592 maHyperlinkHandlers.clear();
593 mpTickEvent.reset();
596 // XMouseListener implementation
597 bool EventMultiplexerImpl::notifyMouseHandlers(
598 const ImplMouseHandlers& rQueue,
599 bool (MouseEventHandler::*pHandlerMethod)( const awt::MouseEvent& ),
600 const awt::MouseEvent& e )
602 uno::Reference<presentation::XSlideShowView> xView(
603 e.Source, uno::UNO_QUERY );
605 ENSURE_OR_RETURN_FALSE( xView.is(), "EventMultiplexer::notifyHandlers(): "
606 "event source is not an XSlideShowView" );
608 // find corresponding view (to map mouse position into user
609 // coordinate space)
610 UnoViewVector::const_iterator aIter;
611 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
612 if( (aIter=::std::find_if(
613 mrViewContainer.begin(),
614 aEnd,
615 boost::bind( std::equal_to< uno::Reference<
616 presentation::XSlideShowView > >(),
617 boost::cref( xView ),
618 boost::bind( &UnoView::getUnoView, _1 ) ) ) ) == aEnd)
620 ENSURE_OR_RETURN_FALSE(
621 false, "EventMultiplexer::notifyHandlers(): "
622 "event source not found under registered views" );
625 // convert mouse position to user coordinate space
626 ::basegfx::B2DPoint aPosition( e.X, e.Y );
627 ::basegfx::B2DHomMatrix aMatrix( (*aIter)->getTransformation() );
628 if( !aMatrix.invert() )
629 ENSURE_OR_THROW( false, "EventMultiplexer::notifyHandlers():"
630 " view matrix singular" );
631 aPosition *= aMatrix;
633 awt::MouseEvent aEvent( e );
634 aEvent.X = ::basegfx::fround( aPosition.getX() );
635 aEvent.Y = ::basegfx::fround( aPosition.getY() );
637 // fire event on handlers, try in order of precedence. If
638 // one high-priority handler rejects the event
639 // (i.e. returns false), try next handler.
640 return rQueue.apply(
641 boost::bind(
642 pHandlerMethod,
643 boost::bind(
644 &ImplMouseHandlers::container_type::value_type::getHandler,
645 _1 ),
646 aEvent ));
649 void EventMultiplexerImpl::mousePressed( const awt::MouseEvent& e )
651 // fire double-click events for every second click
652 sal_Int32 nCurrClickCount = e.ClickCount;
653 while( nCurrClickCount > 1 &&
654 notifyMouseHandlers( maMouseDoubleClickHandlers,
655 &MouseEventHandler::handleMousePressed,
656 e ))
658 nCurrClickCount -= 2;
661 // fire single-click events for all remaining clicks
662 while( nCurrClickCount > 0 &&
663 notifyMouseHandlers( maMouseClickHandlers,
664 &MouseEventHandler::handleMousePressed,
665 e ))
667 --nCurrClickCount;
671 void EventMultiplexerImpl::mouseReleased( const awt::MouseEvent& e )
673 // fire double-click events for every second click
674 sal_Int32 nCurrClickCount = e.ClickCount;
675 while( nCurrClickCount > 1 &&
676 notifyMouseHandlers( maMouseDoubleClickHandlers,
677 &MouseEventHandler::handleMouseReleased,
678 e ))
680 nCurrClickCount -= 2;
683 // fire single-click events for all remaining clicks
684 while( nCurrClickCount > 0 &&
685 notifyMouseHandlers( maMouseClickHandlers,
686 &MouseEventHandler::handleMouseReleased,
687 e ))
689 --nCurrClickCount;
693 void EventMultiplexerImpl::mouseDragged( const awt::MouseEvent& e )
695 notifyMouseHandlers( maMouseMoveHandlers,
696 &MouseEventHandler::handleMouseDragged,
697 e );
700 void EventMultiplexerImpl::mouseMoved( const awt::MouseEvent& e )
702 notifyMouseHandlers( maMouseMoveHandlers,
703 &MouseEventHandler::handleMouseMoved,
704 e );
707 bool EventMultiplexerImpl::notifyNextEffect()
709 // fire event on handlers, try in order of precedence. If one
710 // high-priority handler rejects the event (i.e. returns false),
711 // try next handler.
712 return maNextEffectHandlers.apply(
713 boost::bind(
714 &EventHandler::handleEvent,
715 boost::bind(
716 &ImplNextEffectHandlers::container_type::value_type::getHandler,
717 _1 )) );
720 //////////////////////////////////////////////////////////////////////////
723 EventMultiplexer::EventMultiplexer( EventQueue& rEventQueue,
724 UnoViewContainer const& rViewContainer ) :
725 mpImpl( new EventMultiplexerImpl(rEventQueue, rViewContainer) )
729 EventMultiplexer::~EventMultiplexer()
731 // outline because of EventMultiplexerImpl's incomplete type
734 void EventMultiplexer::clear()
736 mpImpl->clear();
739 void EventMultiplexer::setAutomaticMode( bool bIsAuto )
741 if( bIsAuto == mpImpl->mbIsAutoMode )
742 return; // no change, nothing to do
744 mpImpl->mbIsAutoMode = bIsAuto;
746 mpImpl->handleTicks();
749 bool EventMultiplexer::getAutomaticMode() const
751 return mpImpl->mbIsAutoMode;
754 void EventMultiplexer::setAutomaticTimeout( double nTimeout )
756 mpImpl->mnTimeout = nTimeout;
759 double EventMultiplexer::getAutomaticTimeout() const
761 return mpImpl->mnTimeout;
764 void EventMultiplexer::addNextEffectHandler(
765 EventHandlerSharedPtr const& rHandler,
766 double nPriority )
768 mpImpl->maNextEffectHandlers.addSorted(
769 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
770 rHandler,
771 nPriority) );
773 // Enable tick events, if not done already
774 mpImpl->handleTicks();
777 void EventMultiplexer::removeNextEffectHandler(
778 const EventHandlerSharedPtr& rHandler )
780 mpImpl->maNextEffectHandlers.remove(
781 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
782 rHandler,
783 0.0) );
786 void EventMultiplexer::addSlideStartHandler(
787 const EventHandlerSharedPtr& rHandler )
789 mpImpl->maSlideStartHandlers.add( rHandler );
792 void EventMultiplexer::removeSlideStartHandler(
793 const EventHandlerSharedPtr& rHandler )
795 mpImpl->maSlideStartHandlers.remove( rHandler );
798 void EventMultiplexer::addSlideEndHandler(
799 const EventHandlerSharedPtr& rHandler )
801 mpImpl->maSlideEndHandlers.add( rHandler );
804 void EventMultiplexer::removeSlideEndHandler(
805 const EventHandlerSharedPtr& rHandler )
807 mpImpl->maSlideEndHandlers.remove( rHandler );
810 void EventMultiplexer::addAnimationStartHandler(
811 const AnimationEventHandlerSharedPtr& rHandler )
813 mpImpl->maAnimationStartHandlers.add( rHandler );
816 void EventMultiplexer::removeAnimationStartHandler(
817 const AnimationEventHandlerSharedPtr& rHandler )
819 mpImpl->maAnimationStartHandlers.remove( rHandler );
822 void EventMultiplexer::addAnimationEndHandler(
823 const AnimationEventHandlerSharedPtr& rHandler )
825 mpImpl->maAnimationEndHandlers.add( rHandler );
828 void EventMultiplexer::removeAnimationEndHandler(
829 const AnimationEventHandlerSharedPtr& rHandler )
831 mpImpl->maAnimationEndHandlers.remove( rHandler );
834 void EventMultiplexer::addSlideAnimationsEndHandler(
835 const EventHandlerSharedPtr& rHandler )
837 mpImpl->maSlideAnimationsEndHandlers.add( rHandler );
840 void EventMultiplexer::removeSlideAnimationsEndHandler(
841 const EventHandlerSharedPtr& rHandler )
843 mpImpl->maSlideAnimationsEndHandlers.remove( rHandler );
846 void EventMultiplexer::addAudioStoppedHandler(
847 const AnimationEventHandlerSharedPtr& rHandler )
849 mpImpl->maAudioStoppedHandlers.add( rHandler );
852 void EventMultiplexer::removeAudioStoppedHandler(
853 const AnimationEventHandlerSharedPtr& rHandler )
855 mpImpl->maAudioStoppedHandlers.remove( rHandler );
858 void EventMultiplexer::addCommandStopAudioHandler(
859 const AnimationEventHandlerSharedPtr& rHandler )
861 mpImpl->maCommandStopAudioHandlers.add( rHandler );
864 void EventMultiplexer::removeCommandStopAudioHandler(
865 const AnimationEventHandlerSharedPtr& rHandler )
867 mpImpl->maCommandStopAudioHandlers.remove( rHandler );
870 void EventMultiplexer::addPauseHandler(
871 const PauseEventHandlerSharedPtr& rHandler )
873 mpImpl->maPauseHandlers.add( rHandler );
876 void EventMultiplexer::removePauseHandler(
877 const PauseEventHandlerSharedPtr& rHandler )
879 mpImpl->maPauseHandlers.remove( rHandler );
882 void EventMultiplexer::addViewHandler(
883 const ViewEventHandlerWeakPtr& rHandler )
885 mpImpl->maViewHandlers.add( rHandler );
888 void EventMultiplexer::removeViewHandler( const ViewEventHandlerWeakPtr& rHandler )
890 mpImpl->maViewHandlers.remove( rHandler );
893 void EventMultiplexer::addViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
895 mpImpl->maViewRepaintHandlers.add( rHandler );
898 void EventMultiplexer::removeViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
900 mpImpl->maViewRepaintHandlers.remove( rHandler );
903 void EventMultiplexer::addShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
905 mpImpl->maShapeListenerHandlers.add( rHandler );
908 void EventMultiplexer::removeShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
910 mpImpl->maShapeListenerHandlers.remove( rHandler );
913 void EventMultiplexer::addUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler )
915 mpImpl->maUserPaintEventHandlers.add( rHandler );
918 void EventMultiplexer::addClickHandler(
919 const MouseEventHandlerSharedPtr& rHandler,
920 double nPriority )
922 mpImpl->addMouseHandler(
923 mpImpl->maMouseClickHandlers,
924 rHandler,
925 nPriority,
926 mpImpl->isMouseListenerRegistered()
927 ? NULL
928 : &presentation::XSlideShowView::addMouseListener );
931 void EventMultiplexer::removeClickHandler(
932 const MouseEventHandlerSharedPtr& rHandler )
934 mpImpl->maMouseClickHandlers.remove(
935 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
936 rHandler,
937 0.0) );
939 if( !mpImpl->isMouseListenerRegistered() )
940 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
943 void EventMultiplexer::addDoubleClickHandler(
944 const MouseEventHandlerSharedPtr& rHandler,
945 double nPriority )
947 mpImpl->addMouseHandler(
948 mpImpl->maMouseDoubleClickHandlers,
949 rHandler,
950 nPriority,
951 mpImpl->isMouseListenerRegistered()
952 ? NULL
953 : &presentation::XSlideShowView::addMouseListener );
956 void EventMultiplexer::removeDoubleClickHandler(
957 const MouseEventHandlerSharedPtr& rHandler )
959 mpImpl->maMouseDoubleClickHandlers.remove(
960 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
961 rHandler,
962 0.0) );
964 if( !mpImpl->isMouseListenerRegistered() )
965 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
968 void EventMultiplexer::addMouseMoveHandler(
969 const MouseEventHandlerSharedPtr& rHandler,
970 double nPriority )
972 mpImpl->addMouseHandler(
973 mpImpl->maMouseMoveHandlers,
974 rHandler,
975 nPriority,
976 mpImpl->maMouseMoveHandlers.isEmpty()
977 ? &presentation::XSlideShowView::addMouseMotionListener
978 : NULL );
981 void EventMultiplexer::removeMouseMoveHandler(
982 const MouseEventHandlerSharedPtr& rHandler )
984 mpImpl->maMouseMoveHandlers.remove(
985 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
986 rHandler,
987 0.0) );
989 if( mpImpl->maMouseMoveHandlers.isEmpty() )
990 mpImpl->forEachView(
991 &presentation::XSlideShowView::removeMouseMotionListener );
994 void EventMultiplexer::addHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler,
995 double nPriority )
997 mpImpl->maHyperlinkHandlers.addSorted(
998 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
999 rHandler,
1000 nPriority) );
1003 void EventMultiplexer::removeHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler )
1005 mpImpl->maHyperlinkHandlers.remove(
1006 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
1007 rHandler,
1008 0.0) );
1011 bool EventMultiplexer::notifyShapeListenerAdded(
1012 const uno::Reference<presentation::XShapeEventListener>& xListener,
1013 const uno::Reference<drawing::XShape>& xShape )
1015 return mpImpl->maShapeListenerHandlers.applyAll(
1016 boost::bind(&ShapeListenerEventHandler::listenerAdded,
1018 boost::cref(xListener),
1019 boost::cref(xShape)) );
1022 bool EventMultiplexer::notifyShapeListenerRemoved(
1023 const uno::Reference<presentation::XShapeEventListener>& xListener,
1024 const uno::Reference<drawing::XShape>& xShape )
1026 return mpImpl->maShapeListenerHandlers.applyAll(
1027 boost::bind(&ShapeListenerEventHandler::listenerRemoved,
1029 boost::cref(xListener),
1030 boost::cref(xShape)) );
1033 bool EventMultiplexer::notifyShapeCursorChange(
1034 const uno::Reference<drawing::XShape>& xShape,
1035 sal_Int16 nPointerShape )
1037 return mpImpl->maShapeCursorHandlers.applyAll(
1038 boost::bind(&ShapeCursorEventHandler::cursorChanged,
1040 boost::cref(xShape),
1041 nPointerShape));
1044 bool EventMultiplexer::notifyUserPaintColor( RGBColor const& rUserColor )
1046 return mpImpl->maUserPaintEventHandlers.applyAll(
1047 boost::bind(&UserPaintEventHandler::colorChanged,
1049 boost::cref(rUserColor)));
1052 bool EventMultiplexer::notifyUserPaintStrokeWidth( double rUserStrokeWidth )
1054 return mpImpl->maUserPaintEventHandlers.applyAll(
1055 boost::bind(&UserPaintEventHandler::widthChanged,
1057 rUserStrokeWidth));
1060 bool EventMultiplexer::notifyUserPaintDisabled()
1062 return mpImpl->maUserPaintEventHandlers.applyAll(
1063 boost::mem_fn(&UserPaintEventHandler::disable));
1066 bool EventMultiplexer::notifySwitchPenMode(){
1067 return mpImpl->maUserPaintEventHandlers.applyAll(
1068 boost::mem_fn(&UserPaintEventHandler::switchPenMode));
1071 bool EventMultiplexer::notifySwitchEraserMode(){
1072 return mpImpl->maUserPaintEventHandlers.applyAll(
1073 boost::mem_fn(&UserPaintEventHandler::switchEraserMode));
1076 //adding erasing all ink features with UserPaintOverlay
1077 bool EventMultiplexer::notifyEraseAllInk( bool const& rEraseAllInk )
1079 return mpImpl->maUserPaintEventHandlers.applyAll(
1080 boost::bind(&UserPaintEventHandler::eraseAllInkChanged,
1082 boost::cref(rEraseAllInk)));
1085 //adding erasing features with UserPaintOverlay
1086 bool EventMultiplexer::notifyEraseInkWidth( sal_Int32 rEraseInkSize )
1088 return mpImpl->maUserPaintEventHandlers.applyAll(
1089 boost::bind(&UserPaintEventHandler::eraseInkWidthChanged,
1091 boost::cref(rEraseInkSize)));
1094 bool EventMultiplexer::notifyNextEffect()
1096 return mpImpl->notifyNextEffect();
1099 bool EventMultiplexer::notifySlideStartEvent()
1101 return mpImpl->maSlideStartHandlers.applyAll(
1102 boost::mem_fn(&EventHandler::handleEvent) );
1105 bool EventMultiplexer::notifySlideEndEvent()
1107 return mpImpl->maSlideEndHandlers.applyAll(
1108 boost::mem_fn(&EventHandler::handleEvent) );
1111 bool EventMultiplexer::notifyAnimationStart(
1112 const AnimationNodeSharedPtr& rNode )
1114 return mpImpl->notifyAllAnimationHandlers( mpImpl->maAnimationStartHandlers,
1115 rNode );
1118 bool EventMultiplexer::notifyAnimationEnd(
1119 const AnimationNodeSharedPtr& rNode )
1121 return mpImpl->notifyAllAnimationHandlers( mpImpl->maAnimationEndHandlers,
1122 rNode );
1125 bool EventMultiplexer::notifySlideAnimationsEnd()
1127 return mpImpl->maSlideAnimationsEndHandlers.applyAll(
1128 boost::mem_fn(&EventHandler::handleEvent));
1131 bool EventMultiplexer::notifyAudioStopped(
1132 const AnimationNodeSharedPtr& rNode )
1134 return mpImpl->notifyAllAnimationHandlers(
1135 mpImpl->maAudioStoppedHandlers,
1136 rNode );
1139 bool EventMultiplexer::notifyCommandStopAudio(
1140 const AnimationNodeSharedPtr& rNode )
1142 return mpImpl->notifyAllAnimationHandlers(
1143 mpImpl->maCommandStopAudioHandlers,
1144 rNode );
1147 bool EventMultiplexer::notifyPauseMode( bool bPauseShow )
1149 return mpImpl->maPauseHandlers.applyAll(
1150 boost::bind( &PauseEventHandler::handlePause,
1151 _1, bPauseShow ));
1154 bool EventMultiplexer::notifyViewAdded( const UnoViewSharedPtr& rView )
1156 ENSURE_OR_THROW( rView, "EventMultiplexer::notifyViewAdded(): Invalid view");
1158 // register event listener
1159 uno::Reference<presentation::XSlideShowView> const rUnoView(
1160 rView->getUnoView() );
1162 if( mpImpl->isMouseListenerRegistered() )
1163 rUnoView->addMouseListener(
1164 mpImpl->mxListener.get() );
1166 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1167 rUnoView->addMouseMotionListener(
1168 mpImpl->mxListener.get() );
1170 return mpImpl->maViewHandlers.applyAll(
1171 boost::bind( &ViewEventHandler::viewAdded,
1173 boost::cref(rView) ));
1176 bool EventMultiplexer::notifyViewRemoved( const UnoViewSharedPtr& rView )
1178 ENSURE_OR_THROW( rView,
1179 "EventMultiplexer::removeView(): Invalid view" );
1181 // revoke event listeners
1182 uno::Reference<presentation::XSlideShowView> const rUnoView(
1183 rView->getUnoView() );
1185 if( mpImpl->isMouseListenerRegistered() )
1186 rUnoView->removeMouseListener(
1187 mpImpl->mxListener.get() );
1189 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1190 rUnoView->removeMouseMotionListener(
1191 mpImpl->mxListener.get() );
1193 return mpImpl->maViewHandlers.applyAll(
1194 boost::bind( &ViewEventHandler::viewRemoved,
1196 boost::cref(rView) ));
1199 bool EventMultiplexer::notifyViewChanged( const UnoViewSharedPtr& rView )
1201 return mpImpl->maViewHandlers.applyAll(
1202 boost::bind( &ViewEventHandler::viewChanged,
1204 boost::cref(rView) ));
1207 bool EventMultiplexer::notifyViewChanged( const uno::Reference<presentation::XSlideShowView>& xView )
1209 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1211 if( !pView )
1212 return false; // view not registered here
1214 return notifyViewChanged( pView );
1217 bool EventMultiplexer::notifyViewsChanged()
1219 return mpImpl->maViewHandlers.applyAll(
1220 boost::mem_fn( &ViewEventHandler::viewsChanged ));
1223 bool EventMultiplexer::notifyViewClobbered(
1224 const uno::Reference<presentation::XSlideShowView>& xView )
1226 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1228 if( !pView )
1229 return false; // view not registered here
1231 return mpImpl->maViewRepaintHandlers.applyAll(
1232 boost::bind( &ViewRepaintHandler::viewClobbered,
1234 boost::cref(pView) ));
1237 bool EventMultiplexer::notifyHyperlinkClicked(
1238 OUString const& hyperLink )
1240 return mpImpl->maHyperlinkHandlers.apply(
1241 boost::bind(&HyperlinkHandler::handleHyperlink,
1243 boost::cref(hyperLink)) );
1246 bool EventMultiplexer::notifySlideTransitionStarted()
1248 return true;
1251 } // namespace internal
1252 } // namespace presentation
1254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */