build fix
[LibreOffice.git] / slideshow / source / engine / eventmultiplexer.cxx
blob472d85d82d65fa988c42ec951c9b69be66078be0
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 #include <tools/diagnose_ex.h>
23 #include <rtl/ref.hxx>
24 #include <cppuhelper/compbase.hxx>
25 #include <cppuhelper/basemutex.hxx>
27 #include <com/sun/star/awt/XMouseListener.hpp>
28 #include <com/sun/star/awt/XMouseMotionListener.hpp>
29 #include <com/sun/star/awt/SystemPointer.hpp>
30 #include <com/sun/star/awt/XWindow.hpp>
31 #include <com/sun/star/awt/MouseButton.hpp>
32 #include <com/sun/star/presentation/XSlideShowView.hpp>
34 #include <basegfx/matrix/b2dhommatrix.hxx>
35 #include <basegfx/numeric/ftools.hxx>
37 #include "tools.hxx"
38 #include "eventqueue.hxx"
39 #include "eventmultiplexer.hxx"
40 #include "listenercontainer.hxx"
41 #include "delayevent.hxx"
42 #include "unoview.hxx"
43 #include "unoviewcontainer.hxx"
45 #include <functional>
46 #include <memory>
47 #include <algorithm>
48 #include <vector>
50 using namespace ::com::sun::star;
53 namespace std
55 // add operator== for weak_ptr, so we can use std::find over lists of them
56 template<typename T> bool operator==( weak_ptr<T> const& rLHS,
57 weak_ptr<T> const& rRHS )
59 return rLHS.lock().get() == rRHS.lock().get();
63 namespace slideshow {
64 namespace internal {
66 template <typename HandlerT>
67 class PrioritizedHandlerEntry
69 typedef std::shared_ptr<HandlerT> HandlerSharedPtrT;
70 HandlerSharedPtrT mpHandler;
71 double mnPrio;
73 public:
74 PrioritizedHandlerEntry( HandlerSharedPtrT const& pHandler,
75 double nPrio ) :
76 mpHandler(pHandler),
77 mnPrio(nPrio)
80 HandlerSharedPtrT const& getHandler() const { return mpHandler; }
82 /// To sort according to priority
83 bool operator<( PrioritizedHandlerEntry const& rRHS ) const
85 // reversed order - high prioritized entries
86 // should be at the beginning of the queue
87 return mnPrio > rRHS.mnPrio;
90 /// To permit std::remove in removeHandler template
91 bool operator==( PrioritizedHandlerEntry const& rRHS ) const
93 // ignore prio, for removal, only the handler ptr matters
94 return mpHandler == rRHS.mpHandler;
99 typedef cppu::WeakComponentImplHelper<
100 awt::XMouseListener,
101 awt::XMouseMotionListener > Listener_UnoBase;
103 /** Listener class, to decouple UNO lifetime from EventMultiplexer
105 This class gets registered as the XMouse(Motion)Listener on the
106 XSlideViews, and passes on the events to the EventMultiplexer (via
107 EventQueue indirection, to force the events into the main thread)
109 class EventMultiplexerListener : private cppu::BaseMutex,
110 public Listener_UnoBase
112 public:
113 EventMultiplexerListener( EventQueue& rEventQueue,
114 EventMultiplexerImpl& rEventMultiplexer ) :
115 Listener_UnoBase( m_aMutex ),
116 mpEventQueue( &rEventQueue ),
117 mpEventMultiplexer( &rEventMultiplexer )
121 EventMultiplexerListener( const EventMultiplexerListener& ) = delete;
122 EventMultiplexerListener& operator=( const EventMultiplexerListener& ) = delete;
124 // WeakComponentImplHelperBase::disposing
125 virtual void SAL_CALL disposing() override;
127 private:
128 virtual void SAL_CALL disposing( const lang::EventObject& Source )
129 throw (uno::RuntimeException, std::exception) override;
131 // XMouseListener implementation
132 virtual void SAL_CALL mousePressed( const awt::MouseEvent& e )
133 throw (uno::RuntimeException, std::exception) override;
134 virtual void SAL_CALL mouseReleased( const awt::MouseEvent& e )
135 throw (uno::RuntimeException, std::exception) override;
136 virtual void SAL_CALL mouseEntered( const awt::MouseEvent& e )
137 throw (uno::RuntimeException, std::exception) override;
138 virtual void SAL_CALL mouseExited( const awt::MouseEvent& e )
139 throw (uno::RuntimeException, std::exception) override;
141 // XMouseMotionListener implementation
142 virtual void SAL_CALL mouseDragged( const awt::MouseEvent& e )
143 throw (uno::RuntimeException, std::exception) override;
144 virtual void SAL_CALL mouseMoved( const awt::MouseEvent& e )
145 throw (uno::RuntimeException, std::exception) override;
148 EventQueue* mpEventQueue;
149 EventMultiplexerImpl* mpEventMultiplexer;
153 struct EventMultiplexerImpl
155 EventMultiplexerImpl( EventQueue& rEventQueue,
156 UnoViewContainer const& rViewContainer ) :
157 mrEventQueue(rEventQueue),
158 mrViewContainer(rViewContainer),
159 mxListener( new EventMultiplexerListener(rEventQueue,
160 *this) ),
161 maNextEffectHandlers(),
162 maSlideStartHandlers(),
163 maSlideEndHandlers(),
164 maAnimationStartHandlers(),
165 maAnimationEndHandlers(),
166 maSlideAnimationsEndHandlers(),
167 maAudioStoppedHandlers(),
168 maCommandStopAudioHandlers(),
169 maPauseHandlers(),
170 maViewHandlers(),
171 maViewRepaintHandlers(),
172 maShapeListenerHandlers(),
173 maUserPaintEventHandlers(),
174 maMouseClickHandlers(),
175 maMouseDoubleClickHandlers(),
176 maMouseMoveHandlers(),
177 maHyperlinkHandlers(),
178 mnTimeout(0.0),
179 mpTickEvent(),
180 mbIsAutoMode(false)
183 ~EventMultiplexerImpl()
185 if( mxListener.is() )
186 mxListener->dispose();
189 /// Remove all handlers
190 void clear();
192 // actual handler callbacks (get called from the UNO interface
193 // listeners via event queue)
194 void mousePressed( const awt::MouseEvent& e );
195 void mouseReleased( const awt::MouseEvent& e );
196 void mouseDragged( const awt::MouseEvent& e );
197 void mouseMoved( const awt::MouseEvent& e );
199 bool isMouseListenerRegistered() const;
201 typedef ThreadUnsafeListenerContainer<
202 PrioritizedHandlerEntry<EventHandler>,
203 std::vector<
204 PrioritizedHandlerEntry<EventHandler> > > ImplNextEffectHandlers;
205 typedef PrioritizedHandlerEntry<MouseEventHandler> ImplMouseHandlerEntry;
206 typedef ThreadUnsafeListenerContainer<
207 ImplMouseHandlerEntry,
208 std::vector<ImplMouseHandlerEntry> > ImplMouseHandlers;
209 typedef ThreadUnsafeListenerContainer<
210 EventHandlerSharedPtr,
211 std::vector<EventHandlerSharedPtr> > ImplEventHandlers;
212 typedef ThreadUnsafeListenerContainer<
213 AnimationEventHandlerSharedPtr,
214 std::vector<AnimationEventHandlerSharedPtr> > ImplAnimationHandlers;
215 typedef ThreadUnsafeListenerContainer<
216 PauseEventHandlerSharedPtr,
217 std::vector<PauseEventHandlerSharedPtr> > ImplPauseHandlers;
218 typedef ThreadUnsafeListenerContainer<
219 ViewEventHandlerWeakPtr,
220 std::vector<ViewEventHandlerWeakPtr> > ImplViewHandlers;
221 typedef ThreadUnsafeListenerContainer<
222 ViewRepaintHandlerSharedPtr,
223 std::vector<ViewRepaintHandlerSharedPtr> > ImplRepaintHandlers;
224 typedef ThreadUnsafeListenerContainer<
225 ShapeListenerEventHandlerSharedPtr,
226 std::vector<ShapeListenerEventHandlerSharedPtr> > ImplShapeListenerHandlers;
227 typedef ThreadUnsafeListenerContainer<
228 UserPaintEventHandlerSharedPtr,
229 std::vector<UserPaintEventHandlerSharedPtr> > ImplUserPaintEventHandlers;
230 typedef ThreadUnsafeListenerContainer<
231 PrioritizedHandlerEntry<HyperlinkHandler>,
232 std::vector<PrioritizedHandlerEntry<HyperlinkHandler> > > ImplHyperLinkHandlers;
234 template <typename XSlideShowViewFunc>
235 void forEachView( XSlideShowViewFunc pViewMethod );
237 UnoViewSharedPtr findUnoView(const uno::Reference<
238 presentation::XSlideShowView>& xView) const;
240 template< typename RegisterFunction >
241 void addMouseHandler( ImplMouseHandlers& rHandlerContainer,
242 const MouseEventHandlerSharedPtr& rHandler,
243 double nPriority,
244 RegisterFunction pRegisterListener );
246 static bool notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
247 AnimationNodeSharedPtr const& rNode );
249 bool notifyMouseHandlers(
250 const ImplMouseHandlers& rQueue,
251 bool (MouseEventHandler::*pHandlerMethod)(
252 const awt::MouseEvent& ),
253 const awt::MouseEvent& e );
255 bool notifyNextEffect();
257 /// Called for automatic nextEffect
258 void tick();
260 /// Schedules a tick event
261 void scheduleTick();
263 /// Schedules tick events, if mbIsAutoMode is true
264 void handleTicks();
267 EventQueue& mrEventQueue;
268 UnoViewContainer const& mrViewContainer;
269 ::rtl::Reference<
270 EventMultiplexerListener> mxListener;
272 ImplNextEffectHandlers maNextEffectHandlers;
273 ImplEventHandlers maSlideStartHandlers;
274 ImplEventHandlers maSlideEndHandlers;
275 ImplAnimationHandlers maAnimationStartHandlers;
276 ImplAnimationHandlers maAnimationEndHandlers;
277 ImplEventHandlers maSlideAnimationsEndHandlers;
278 ImplAnimationHandlers maAudioStoppedHandlers;
279 ImplAnimationHandlers maCommandStopAudioHandlers;
280 ImplPauseHandlers maPauseHandlers;
281 ImplViewHandlers maViewHandlers;
282 ImplRepaintHandlers maViewRepaintHandlers;
283 ImplShapeListenerHandlers maShapeListenerHandlers;
284 ImplUserPaintEventHandlers maUserPaintEventHandlers;
285 ImplMouseHandlers maMouseClickHandlers;
286 ImplMouseHandlers maMouseDoubleClickHandlers;
287 ImplMouseHandlers maMouseMoveHandlers;
288 ImplHyperLinkHandlers maHyperlinkHandlers;
290 /// automatic next effect mode timeout
291 double mnTimeout;
293 /** Holds ptr to optional tick event weakly
295 When event queue is cleansed, the next
296 setAutomaticMode(true) call is then able to
297 regenerate the event.
299 ::std::weak_ptr< Event > mpTickEvent;
300 bool mbIsAutoMode;
304 void SAL_CALL EventMultiplexerListener::disposing()
306 osl::MutexGuard const guard( m_aMutex );
307 mpEventQueue = nullptr;
308 mpEventMultiplexer = nullptr;
311 void SAL_CALL EventMultiplexerListener::disposing(
312 const lang::EventObject& /*rSource*/ ) throw (uno::RuntimeException, std::exception)
314 // there's no real point in acting on this message - after all,
315 // the event sources are the XSlideShowViews, which must be
316 // explicitly removed from the slideshow via
317 // XSlideShow::removeView(). thus, if a XSlideShowView has
318 // properly removed itself from the slideshow, it will not be
319 // found here. and if it hasn't, there'll be other references at
320 // other places within the slideshow, anyway...
323 void SAL_CALL EventMultiplexerListener::mousePressed(
324 const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
326 osl::MutexGuard const guard( m_aMutex );
328 // notify mouse press. Don't call handlers directly, this
329 // might not be the main thread!
330 if( mpEventQueue )
331 mpEventQueue->addEvent(
332 makeEvent( std::bind( &EventMultiplexerImpl::mousePressed,
333 mpEventMultiplexer,
334 e ),
335 "EventMultiplexerImpl::mousePressed") );
338 void SAL_CALL EventMultiplexerListener::mouseReleased(
339 const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
341 osl::MutexGuard const guard( m_aMutex );
343 // notify mouse release. Don't call handlers directly,
344 // this might not be the main thread!
345 if( mpEventQueue )
346 mpEventQueue->addEvent(
347 makeEvent( std::bind( &EventMultiplexerImpl::mouseReleased,
348 mpEventMultiplexer,
349 e ),
350 "EventMultiplexerImpl::mouseReleased") );
353 void SAL_CALL EventMultiplexerListener::mouseEntered(
354 const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException, std::exception)
356 // not used here
359 void SAL_CALL EventMultiplexerListener::mouseExited(
360 const awt::MouseEvent& /*e*/ ) throw (uno::RuntimeException, std::exception)
362 // not used here
365 // XMouseMotionListener implementation
366 void SAL_CALL EventMultiplexerListener::mouseDragged(
367 const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
369 osl::MutexGuard const guard( m_aMutex );
371 // notify mouse drag. Don't call handlers directly, this
372 // might not be the main thread!
373 if( mpEventQueue )
374 mpEventQueue->addEvent(
375 makeEvent( std::bind( &EventMultiplexerImpl::mouseDragged,
376 mpEventMultiplexer,
377 e ),
378 "EventMultiplexerImpl::mouseDragged") );
381 void SAL_CALL EventMultiplexerListener::mouseMoved(
382 const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
384 osl::MutexGuard const guard( m_aMutex );
386 // notify mouse move. Don't call handlers directly, this
387 // might not be the main thread!
388 if( mpEventQueue )
389 mpEventQueue->addEvent(
390 makeEvent( std::bind( &EventMultiplexerImpl::mouseMoved,
391 mpEventMultiplexer,
392 e ),
393 "EventMultiplexerImpl::mouseMoved") );
397 bool EventMultiplexerImpl::notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
398 AnimationNodeSharedPtr const& rNode )
400 return rContainer.applyAll(
401 [&rNode]( const AnimationEventHandlerSharedPtr& pEventHandler )
402 { return pEventHandler->handleAnimationEvent( rNode ); } );
405 template <typename XSlideShowViewFunc>
406 void EventMultiplexerImpl::forEachView( XSlideShowViewFunc pViewMethod )
408 if( pViewMethod )
410 // (un)register mouse listener on all views
411 for( UnoViewVector::const_iterator aIter( mrViewContainer.begin() ),
412 aEnd( mrViewContainer.end() ); aIter != aEnd; ++aIter )
414 uno::Reference<presentation::XSlideShowView> xView ((*aIter)->getUnoView());
415 if (xView.is())
417 (xView.get()->*pViewMethod)( mxListener.get() );
419 else
421 OSL_ASSERT(xView.is());
427 UnoViewSharedPtr EventMultiplexerImpl::findUnoView(
428 const uno::Reference<presentation::XSlideShowView>& xView) const
430 // find view from which the change originated
431 UnoViewVector::const_iterator aIter;
432 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
433 if( (aIter=std::find_if( mrViewContainer.begin(),
434 aEnd,
435 [&xView]( const UnoViewSharedPtr& pView )
436 { return xView == pView->getUnoView(); } )) == aEnd )
438 OSL_FAIL("EventMultiplexer::findUnoView(): unexpected message source" );
439 return UnoViewSharedPtr();
442 return *aIter;
445 template< typename RegisterFunction >
446 void EventMultiplexerImpl::addMouseHandler(
447 ImplMouseHandlers& rHandlerContainer,
448 const MouseEventHandlerSharedPtr& rHandler,
449 double nPriority,
450 RegisterFunction pRegisterListener )
452 ENSURE_OR_THROW(
453 rHandler,
454 "EventMultiplexer::addMouseHandler(): Invalid handler" );
456 // register mouse listener on all views
457 forEachView( pRegisterListener );
459 // add into sorted container:
460 rHandlerContainer.addSorted(
461 typename ImplMouseHandlers::container_type::value_type(
462 rHandler,
463 nPriority ));
466 bool EventMultiplexerImpl::isMouseListenerRegistered() const
468 return !(maMouseClickHandlers.isEmpty() &&
469 maMouseDoubleClickHandlers.isEmpty());
472 void EventMultiplexerImpl::tick()
474 if( !mbIsAutoMode )
475 return; // this event is just a left-over, ignore
477 notifyNextEffect();
479 if( !maNextEffectHandlers.isEmpty() )
481 // still handlers left, schedule next timeout
482 // event. Will also set mbIsTickEventOn back to true
483 scheduleTick();
487 void EventMultiplexerImpl::scheduleTick()
489 EventSharedPtr pEvent(
490 makeDelay( [this] () { this->tick(); },
491 mnTimeout,
492 "EventMultiplexerImpl::tick with delay"));
494 // store weak reference to generated event, to notice when
495 // the event queue gets cleansed (we then have to
496 // regenerate the tick event!)
497 mpTickEvent = pEvent;
499 // enabled auto mode: simply schedule a timeout event,
500 // which will eventually call our tick() method
501 mrEventQueue.addEventForNextRound( pEvent );
504 void EventMultiplexerImpl::handleTicks()
506 if( !mbIsAutoMode )
507 return; // nothing to do, don't need no ticks
509 EventSharedPtr pTickEvent( mpTickEvent.lock() );
510 if( pTickEvent )
511 return; // nothing to do, there's already a tick
512 // pending
514 // schedule initial tick (which reschedules itself
515 // after that, all by itself)
516 scheduleTick();
520 void EventMultiplexerImpl::clear()
522 // deregister from all views.
523 if( isMouseListenerRegistered() )
525 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
526 aEnd=mrViewContainer.end();
527 aIter!=aEnd;
528 ++aIter )
530 if( (*aIter)->getUnoView().is() )
531 (*aIter)->getUnoView()->removeMouseListener( mxListener.get() );
535 if( !maMouseMoveHandlers.isEmpty() )
537 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
538 aEnd=mrViewContainer.end();
539 aIter!=aEnd;
540 ++aIter )
542 if( (*aIter)->getUnoView().is() )
543 (*aIter)->getUnoView()->removeMouseMotionListener( mxListener.get() );
547 // clear all handlers (releases all references)
548 maNextEffectHandlers.clear();
549 maSlideStartHandlers.clear();
550 maSlideEndHandlers.clear();
551 maAnimationStartHandlers.clear();
552 maAnimationEndHandlers.clear();
553 maSlideAnimationsEndHandlers.clear();
554 maAudioStoppedHandlers.clear();
555 maCommandStopAudioHandlers.clear();
556 maPauseHandlers.clear();
557 maViewHandlers.clear();
558 maViewRepaintHandlers.clear();
559 maMouseClickHandlers.clear();
560 maMouseDoubleClickHandlers.clear();
561 maMouseMoveHandlers.clear();
562 maHyperlinkHandlers.clear();
563 mpTickEvent.reset();
566 // XMouseListener implementation
567 bool EventMultiplexerImpl::notifyMouseHandlers(
568 const ImplMouseHandlers& rQueue,
569 bool (MouseEventHandler::*pHandlerMethod)( const awt::MouseEvent& ),
570 const awt::MouseEvent& e )
572 uno::Reference<presentation::XSlideShowView> xView(
573 e.Source, uno::UNO_QUERY );
575 ENSURE_OR_RETURN_FALSE( xView.is(), "EventMultiplexer::notifyHandlers(): "
576 "event source is not an XSlideShowView" );
578 // find corresponding view (to map mouse position into user
579 // coordinate space)
580 UnoViewVector::const_iterator aIter;
581 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
582 if( (aIter=::std::find_if(
583 mrViewContainer.begin(),
584 aEnd,
585 [&xView]( const UnoViewSharedPtr& pView )
586 { return xView == pView->getUnoView(); } )) == aEnd )
588 ENSURE_OR_RETURN_FALSE(
589 false, "EventMultiplexer::notifyHandlers(): "
590 "event source not found under registered views" );
593 // convert mouse position to user coordinate space
594 ::basegfx::B2DPoint aPosition( e.X, e.Y );
595 ::basegfx::B2DHomMatrix aMatrix( (*aIter)->getTransformation() );
596 if( !aMatrix.invert() )
597 ENSURE_OR_THROW( false, "EventMultiplexer::notifyHandlers():"
598 " view matrix singular" );
599 aPosition *= aMatrix;
601 awt::MouseEvent aEvent( e );
602 aEvent.X = ::basegfx::fround( aPosition.getX() );
603 aEvent.Y = ::basegfx::fround( aPosition.getY() );
605 // fire event on handlers, try in order of precedence. If
606 // one high-priority handler rejects the event
607 // (i.e. returns false), try next handler.
608 return rQueue.apply(
609 [&pHandlerMethod, &aEvent]( const ImplMouseHandlerEntry& rMouseHandler )
610 { return ( ( *rMouseHandler.getHandler() ).*pHandlerMethod )( aEvent ); } );
613 void EventMultiplexerImpl::mousePressed( const awt::MouseEvent& e )
615 // fire double-click events for every second click
616 sal_Int32 nCurrClickCount = e.ClickCount;
617 while( nCurrClickCount > 1 &&
618 notifyMouseHandlers( maMouseDoubleClickHandlers,
619 &MouseEventHandler::handleMousePressed,
620 e ))
622 nCurrClickCount -= 2;
625 // fire single-click events for all remaining clicks
626 while( nCurrClickCount > 0 &&
627 notifyMouseHandlers( maMouseClickHandlers,
628 &MouseEventHandler::handleMousePressed,
629 e ))
631 --nCurrClickCount;
635 void EventMultiplexerImpl::mouseReleased( const awt::MouseEvent& e )
637 // fire double-click events for every second click
638 sal_Int32 nCurrClickCount = e.ClickCount;
639 while( nCurrClickCount > 1 &&
640 notifyMouseHandlers( maMouseDoubleClickHandlers,
641 &MouseEventHandler::handleMouseReleased,
642 e ))
644 nCurrClickCount -= 2;
647 // fire single-click events for all remaining clicks
648 while( nCurrClickCount > 0 &&
649 notifyMouseHandlers( maMouseClickHandlers,
650 &MouseEventHandler::handleMouseReleased,
651 e ))
653 --nCurrClickCount;
657 void EventMultiplexerImpl::mouseDragged( const awt::MouseEvent& e )
659 notifyMouseHandlers( maMouseMoveHandlers,
660 &MouseEventHandler::handleMouseDragged,
661 e );
664 void EventMultiplexerImpl::mouseMoved( const awt::MouseEvent& e )
666 notifyMouseHandlers( maMouseMoveHandlers,
667 &MouseEventHandler::handleMouseMoved,
668 e );
671 bool EventMultiplexerImpl::notifyNextEffect()
673 // fire event on handlers, try in order of precedence. If one
674 // high-priority handler rejects the event (i.e. returns false),
675 // try next handler.
676 return maNextEffectHandlers.apply(
677 []( const PrioritizedHandlerEntry< EventHandler >& pHandler )
678 { return pHandler.getHandler()->handleEvent(); } );
682 EventMultiplexer::EventMultiplexer( EventQueue& rEventQueue,
683 UnoViewContainer const& rViewContainer ) :
684 mpImpl( new EventMultiplexerImpl(rEventQueue, rViewContainer) )
688 EventMultiplexer::~EventMultiplexer()
690 // outline because of EventMultiplexerImpl's incomplete type
693 void EventMultiplexer::clear()
695 mpImpl->clear();
698 void EventMultiplexer::setAutomaticMode( bool bIsAuto )
700 if( bIsAuto == mpImpl->mbIsAutoMode )
701 return; // no change, nothing to do
703 mpImpl->mbIsAutoMode = bIsAuto;
705 mpImpl->handleTicks();
708 bool EventMultiplexer::getAutomaticMode() const
710 return mpImpl->mbIsAutoMode;
713 void EventMultiplexer::setAutomaticTimeout( double nTimeout )
715 mpImpl->mnTimeout = nTimeout;
718 double EventMultiplexer::getAutomaticTimeout() const
720 return mpImpl->mnTimeout;
723 void EventMultiplexer::addNextEffectHandler(
724 EventHandlerSharedPtr const& rHandler,
725 double nPriority )
727 mpImpl->maNextEffectHandlers.addSorted(
728 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
729 rHandler,
730 nPriority) );
732 // Enable tick events, if not done already
733 mpImpl->handleTicks();
736 void EventMultiplexer::removeNextEffectHandler(
737 const EventHandlerSharedPtr& rHandler )
739 mpImpl->maNextEffectHandlers.remove(
740 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
741 rHandler,
742 0.0) );
745 void EventMultiplexer::addSlideStartHandler(
746 const EventHandlerSharedPtr& rHandler )
748 mpImpl->maSlideStartHandlers.add( rHandler );
751 void EventMultiplexer::removeSlideStartHandler(
752 const EventHandlerSharedPtr& rHandler )
754 mpImpl->maSlideStartHandlers.remove( rHandler );
757 void EventMultiplexer::addSlideEndHandler(
758 const EventHandlerSharedPtr& rHandler )
760 mpImpl->maSlideEndHandlers.add( rHandler );
763 void EventMultiplexer::removeSlideEndHandler(
764 const EventHandlerSharedPtr& rHandler )
766 mpImpl->maSlideEndHandlers.remove( rHandler );
769 void EventMultiplexer::addAnimationStartHandler(
770 const AnimationEventHandlerSharedPtr& rHandler )
772 mpImpl->maAnimationStartHandlers.add( rHandler );
775 void EventMultiplexer::removeAnimationStartHandler(
776 const AnimationEventHandlerSharedPtr& rHandler )
778 mpImpl->maAnimationStartHandlers.remove( rHandler );
781 void EventMultiplexer::addAnimationEndHandler(
782 const AnimationEventHandlerSharedPtr& rHandler )
784 mpImpl->maAnimationEndHandlers.add( rHandler );
787 void EventMultiplexer::removeAnimationEndHandler(
788 const AnimationEventHandlerSharedPtr& rHandler )
790 mpImpl->maAnimationEndHandlers.remove( rHandler );
793 void EventMultiplexer::addSlideAnimationsEndHandler(
794 const EventHandlerSharedPtr& rHandler )
796 mpImpl->maSlideAnimationsEndHandlers.add( rHandler );
799 void EventMultiplexer::removeSlideAnimationsEndHandler(
800 const EventHandlerSharedPtr& rHandler )
802 mpImpl->maSlideAnimationsEndHandlers.remove( rHandler );
805 void EventMultiplexer::addAudioStoppedHandler(
806 const AnimationEventHandlerSharedPtr& rHandler )
808 mpImpl->maAudioStoppedHandlers.add( rHandler );
811 void EventMultiplexer::removeAudioStoppedHandler(
812 const AnimationEventHandlerSharedPtr& rHandler )
814 mpImpl->maAudioStoppedHandlers.remove( rHandler );
817 void EventMultiplexer::addCommandStopAudioHandler(
818 const AnimationEventHandlerSharedPtr& rHandler )
820 mpImpl->maCommandStopAudioHandlers.add( rHandler );
823 void EventMultiplexer::removeCommandStopAudioHandler(
824 const AnimationEventHandlerSharedPtr& rHandler )
826 mpImpl->maCommandStopAudioHandlers.remove( rHandler );
829 void EventMultiplexer::addPauseHandler(
830 const PauseEventHandlerSharedPtr& rHandler )
832 mpImpl->maPauseHandlers.add( rHandler );
835 void EventMultiplexer::removePauseHandler(
836 const PauseEventHandlerSharedPtr& rHandler )
838 mpImpl->maPauseHandlers.remove( rHandler );
841 void EventMultiplexer::addViewHandler(
842 const ViewEventHandlerWeakPtr& rHandler )
844 mpImpl->maViewHandlers.add( rHandler );
847 void EventMultiplexer::removeViewHandler( const ViewEventHandlerWeakPtr& rHandler )
849 mpImpl->maViewHandlers.remove( rHandler );
852 void EventMultiplexer::addViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
854 mpImpl->maViewRepaintHandlers.add( rHandler );
857 void EventMultiplexer::removeViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler )
859 mpImpl->maViewRepaintHandlers.remove( rHandler );
862 void EventMultiplexer::addShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
864 mpImpl->maShapeListenerHandlers.add( rHandler );
867 void EventMultiplexer::removeShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler )
869 mpImpl->maShapeListenerHandlers.remove( rHandler );
872 void EventMultiplexer::addUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler )
874 mpImpl->maUserPaintEventHandlers.add( rHandler );
877 void EventMultiplexer::addClickHandler(
878 const MouseEventHandlerSharedPtr& rHandler,
879 double nPriority )
881 mpImpl->addMouseHandler(
882 mpImpl->maMouseClickHandlers,
883 rHandler,
884 nPriority,
885 mpImpl->isMouseListenerRegistered()
886 ? nullptr
887 : &presentation::XSlideShowView::addMouseListener );
890 void EventMultiplexer::removeClickHandler(
891 const MouseEventHandlerSharedPtr& rHandler )
893 mpImpl->maMouseClickHandlers.remove(
894 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
895 rHandler,
896 0.0) );
898 if( !mpImpl->isMouseListenerRegistered() )
899 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
902 void EventMultiplexer::addDoubleClickHandler(
903 const MouseEventHandlerSharedPtr& rHandler,
904 double nPriority )
906 mpImpl->addMouseHandler(
907 mpImpl->maMouseDoubleClickHandlers,
908 rHandler,
909 nPriority,
910 mpImpl->isMouseListenerRegistered()
911 ? nullptr
912 : &presentation::XSlideShowView::addMouseListener );
915 void EventMultiplexer::removeDoubleClickHandler(
916 const MouseEventHandlerSharedPtr& rHandler )
918 mpImpl->maMouseDoubleClickHandlers.remove(
919 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
920 rHandler,
921 0.0) );
923 if( !mpImpl->isMouseListenerRegistered() )
924 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
927 void EventMultiplexer::addMouseMoveHandler(
928 const MouseEventHandlerSharedPtr& rHandler,
929 double nPriority )
931 mpImpl->addMouseHandler(
932 mpImpl->maMouseMoveHandlers,
933 rHandler,
934 nPriority,
935 mpImpl->maMouseMoveHandlers.isEmpty()
936 ? &presentation::XSlideShowView::addMouseMotionListener
937 : nullptr );
940 void EventMultiplexer::removeMouseMoveHandler(
941 const MouseEventHandlerSharedPtr& rHandler )
943 mpImpl->maMouseMoveHandlers.remove(
944 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
945 rHandler,
946 0.0) );
948 if( mpImpl->maMouseMoveHandlers.isEmpty() )
949 mpImpl->forEachView(
950 &presentation::XSlideShowView::removeMouseMotionListener );
953 void EventMultiplexer::addHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler,
954 double nPriority )
956 mpImpl->maHyperlinkHandlers.addSorted(
957 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
958 rHandler,
959 nPriority) );
962 void EventMultiplexer::removeHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler )
964 mpImpl->maHyperlinkHandlers.remove(
965 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
966 rHandler,
967 0.0) );
970 void EventMultiplexer::notifyShapeListenerAdded(
971 const uno::Reference<presentation::XShapeEventListener>& xListener,
972 const uno::Reference<drawing::XShape>& xShape )
974 mpImpl->maShapeListenerHandlers.applyAll(
975 [&xListener, &xShape]( const ShapeListenerEventHandlerSharedPtr& pHandler )
976 { return pHandler->listenerAdded( xListener, xShape ); } );
979 void EventMultiplexer::notifyShapeListenerRemoved(
980 const uno::Reference<presentation::XShapeEventListener>& xListener,
981 const uno::Reference<drawing::XShape>& xShape )
983 mpImpl->maShapeListenerHandlers.applyAll(
984 [&xListener, &xShape]( const ShapeListenerEventHandlerSharedPtr& pHandler )
985 { return pHandler->listenerRemoved( xListener, xShape ); } );
988 void EventMultiplexer::notifyUserPaintColor( RGBColor const& rUserColor )
990 mpImpl->maUserPaintEventHandlers.applyAll(
991 [&rUserColor]( const UserPaintEventHandlerSharedPtr& pHandler )
992 { return pHandler->colorChanged( rUserColor ); } );
995 void EventMultiplexer::notifyUserPaintStrokeWidth( double rUserStrokeWidth )
997 mpImpl->maUserPaintEventHandlers.applyAll(
998 [&rUserStrokeWidth]( const UserPaintEventHandlerSharedPtr& pHandler )
999 { return pHandler->widthChanged( rUserStrokeWidth ); } );
1002 void EventMultiplexer::notifyUserPaintDisabled()
1004 mpImpl->maUserPaintEventHandlers.applyAll(
1005 std::mem_fn(&UserPaintEventHandler::disable));
1008 void EventMultiplexer::notifySwitchPenMode(){
1009 mpImpl->maUserPaintEventHandlers.applyAll(
1010 std::mem_fn(&UserPaintEventHandler::switchPenMode));
1013 void EventMultiplexer::notifySwitchEraserMode(){
1014 mpImpl->maUserPaintEventHandlers.applyAll(
1015 std::mem_fn(&UserPaintEventHandler::switchEraserMode));
1018 //adding erasing all ink features with UserPaintOverlay
1019 void EventMultiplexer::notifyEraseAllInk( bool bEraseAllInk )
1021 mpImpl->maUserPaintEventHandlers.applyAll(
1022 [&bEraseAllInk]( const UserPaintEventHandlerSharedPtr& pHandler )
1023 { return pHandler->eraseAllInkChanged( bEraseAllInk ); } );
1026 //adding erasing features with UserPaintOverlay
1027 void EventMultiplexer::notifyEraseInkWidth( sal_Int32 rEraseInkSize )
1029 mpImpl->maUserPaintEventHandlers.applyAll(
1030 [&rEraseInkSize]( const UserPaintEventHandlerSharedPtr& pHandler )
1031 { return pHandler->eraseInkWidthChanged( rEraseInkSize ); } );
1034 bool EventMultiplexer::notifyNextEffect()
1036 return mpImpl->notifyNextEffect();
1039 void EventMultiplexer::notifySlideStartEvent()
1041 mpImpl->maSlideStartHandlers.applyAll(
1042 std::mem_fn(&EventHandler::handleEvent) );
1045 bool EventMultiplexer::notifySlideEndEvent()
1047 return mpImpl->maSlideEndHandlers.applyAll(
1048 std::mem_fn(&EventHandler::handleEvent) );
1051 bool EventMultiplexer::notifyAnimationStart(
1052 const AnimationNodeSharedPtr& rNode )
1054 return EventMultiplexerImpl::notifyAllAnimationHandlers( mpImpl->maAnimationStartHandlers,
1055 rNode );
1058 bool EventMultiplexer::notifyAnimationEnd(
1059 const AnimationNodeSharedPtr& rNode )
1061 return EventMultiplexerImpl::notifyAllAnimationHandlers( mpImpl->maAnimationEndHandlers,
1062 rNode );
1065 bool EventMultiplexer::notifySlideAnimationsEnd()
1067 return mpImpl->maSlideAnimationsEndHandlers.applyAll(
1068 std::mem_fn(&EventHandler::handleEvent));
1071 bool EventMultiplexer::notifyAudioStopped(
1072 const AnimationNodeSharedPtr& rNode )
1074 return EventMultiplexerImpl::notifyAllAnimationHandlers(
1075 mpImpl->maAudioStoppedHandlers,
1076 rNode );
1079 bool EventMultiplexer::notifyCommandStopAudio(
1080 const AnimationNodeSharedPtr& rNode )
1082 return EventMultiplexerImpl::notifyAllAnimationHandlers(
1083 mpImpl->maCommandStopAudioHandlers,
1084 rNode );
1087 void EventMultiplexer::notifyPauseMode( bool bPauseShow )
1089 mpImpl->maPauseHandlers.applyAll(
1090 [&bPauseShow]( const PauseEventHandlerSharedPtr& pHandler )
1091 { return pHandler->handlePause( bPauseShow ); } );
1094 void EventMultiplexer::notifyViewAdded( const UnoViewSharedPtr& rView )
1096 ENSURE_OR_THROW( rView, "EventMultiplexer::notifyViewAdded(): Invalid view");
1098 // register event listener
1099 uno::Reference<presentation::XSlideShowView> const rUnoView(
1100 rView->getUnoView() );
1102 if( mpImpl->isMouseListenerRegistered() )
1103 rUnoView->addMouseListener(
1104 mpImpl->mxListener.get() );
1106 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1107 rUnoView->addMouseMotionListener(
1108 mpImpl->mxListener.get() );
1110 mpImpl->maViewHandlers.applyAll(
1111 [&rView]( const ViewEventHandlerWeakPtr& pHandler )
1112 { return pHandler.lock()->viewAdded( rView ); } );
1115 void EventMultiplexer::notifyViewRemoved( const UnoViewSharedPtr& rView )
1117 ENSURE_OR_THROW( rView,
1118 "EventMultiplexer::removeView(): Invalid view" );
1120 // revoke event listeners
1121 uno::Reference<presentation::XSlideShowView> const rUnoView(
1122 rView->getUnoView() );
1124 if( mpImpl->isMouseListenerRegistered() )
1125 rUnoView->removeMouseListener(
1126 mpImpl->mxListener.get() );
1128 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1129 rUnoView->removeMouseMotionListener(
1130 mpImpl->mxListener.get() );
1132 mpImpl->maViewHandlers.applyAll(
1133 [&rView]( const ViewEventHandlerWeakPtr& pHandler )
1134 { return pHandler.lock()->viewRemoved( rView ); } );
1137 bool EventMultiplexer::notifyViewChanged( const UnoViewSharedPtr& rView )
1139 return mpImpl->maViewHandlers.applyAll(
1140 [&rView]( const ViewEventHandlerWeakPtr& pHandler )
1141 { return pHandler.lock()->viewChanged( rView ); } );
1144 void EventMultiplexer::notifyViewChanged( const uno::Reference<presentation::XSlideShowView>& xView )
1146 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1148 if( !pView )
1149 return; // view not registered here
1151 notifyViewChanged( pView );
1154 void EventMultiplexer::notifyViewsChanged()
1156 mpImpl->maViewHandlers.applyAll(
1157 std::mem_fn( &ViewEventHandler::viewsChanged ));
1160 void EventMultiplexer::notifyViewClobbered(
1161 const uno::Reference<presentation::XSlideShowView>& xView )
1163 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1165 if( !pView )
1166 return; // view not registered here
1168 mpImpl->maViewRepaintHandlers.applyAll(
1169 [&pView]( const ViewRepaintHandlerSharedPtr& pHandler )
1170 { return pHandler->viewClobbered( pView ); } );
1173 void EventMultiplexer::notifyHyperlinkClicked(
1174 OUString const& hyperLink )
1176 mpImpl->maHyperlinkHandlers.apply(
1177 [&hyperLink]( const PrioritizedHandlerEntry< HyperlinkHandler >& pHandler )
1178 { return pHandler.getHandler()->handleHyperlink( hyperLink ); } );
1181 } // namespace internal
1182 } // namespace presentation
1184 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */