LibreOffice Module slideshow (master) 1
eventmultiplexer.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
22
23#include <rtl/ref.hxx>
25
26#include <com/sun/star/awt/XMouseListener.hpp>
27#include <com/sun/star/awt/XMouseMotionListener.hpp>
28#include <com/sun/star/presentation/XSlideShowView.hpp>
29
33
34#include <eventqueue.hxx>
35#include <eventmultiplexer.hxx>
36#include <listenercontainer.hxx>
37#include <delayevent.hxx>
38#include <unoview.hxx>
39#include <unoviewcontainer.hxx>
40
41#include <functional>
42#include <memory>
43#include <algorithm>
44#include <type_traits>
45#include <utility>
46#include <vector>
47
48using namespace ::com::sun::star;
49
50namespace
51{
52 // add operator== for weak_ptr, so we can use std::find over lists of them
53 struct ViewEventHandlerWeakPtrWrapper final {
55
56 ViewEventHandlerWeakPtrWrapper(slideshow::internal::ViewEventHandlerWeakPtr thePtr):
57 ptr(std::move(thePtr)) {}
58
59 bool operator ==(ViewEventHandlerWeakPtrWrapper const & other) const
60 { return ptr.lock().get() == other.ptr.lock().get(); }
61 };
62}
63
64// Needed by ImplViewHandlers; see the ListenerOperations<std::weak_ptr<ListenerTargetT>> partial
65// specialization in slideshow/source/inc/listenercontainer.hxx:
66template<>
67struct slideshow::internal::ListenerOperations<ViewEventHandlerWeakPtrWrapper>
68{
69 template< typename ContainerT,
70 typename FuncT >
71 static bool notifySingleListener( ContainerT& rContainer,
72 FuncT func )
73 {
74 for( const auto& rCurr : rContainer )
75 {
76 std::shared_ptr<ViewEventHandler> pListener( rCurr.ptr.lock() );
77
78 if( pListener && func(pListener) )
79 return true;
80 }
81
82 return false;
83 }
84
85 template< typename ContainerT,
86 typename FuncT >
87 static bool notifyAllListeners( ContainerT& rContainer,
88 FuncT func )
89 {
90 bool bRet(false);
91 for( const auto& rCurr : rContainer )
92 {
93 std::shared_ptr<ViewEventHandler> pListener( rCurr.ptr.lock() );
94
95 if( pListener.get() &&
96 FunctionApply<typename ::std::invoke_result<FuncT, std::shared_ptr<ViewEventHandler> const&>::type,
97 std::shared_ptr<ViewEventHandler> >::apply(func,pListener) )
98 {
99 bRet = true;
100 }
101 }
102
103 return bRet;
104 }
105 template< typename ContainerT >
106 static void pruneListeners( ContainerT& rContainer,
107 size_t nSizeThreshold )
108 {
109 if( rContainer.size() <= nSizeThreshold )
110 return;
111
112 ContainerT aAliveListeners;
113 aAliveListeners.reserve(rContainer.size());
114
115 for( const auto& rCurr : rContainer )
116 {
117 if( !rCurr.ptr.expired() )
118 aAliveListeners.push_back( rCurr );
119 }
120
121 std::swap( rContainer, aAliveListeners );
122 }
123};
124
125namespace slideshow::internal {
126
127namespace {
128
129template <typename HandlerT>
130class PrioritizedHandlerEntry
131{
132 typedef std::shared_ptr<HandlerT> HandlerSharedPtrT;
133 HandlerSharedPtrT mpHandler;
134 double mnPrio;
135
136public:
137 PrioritizedHandlerEntry( HandlerSharedPtrT pHandler,
138 double nPrio ) :
139 mpHandler(std::move(pHandler)),
140 mnPrio(nPrio)
141 {}
142
143 HandlerSharedPtrT const& getHandler() const { return mpHandler; }
144
146 bool operator<( PrioritizedHandlerEntry const& rRHS ) const
147 {
148 // reversed order - high prioritized entries
149 // should be at the beginning of the queue
150 return mnPrio > rRHS.mnPrio;
151 }
152
154 bool operator==( PrioritizedHandlerEntry const& rRHS ) const
155 {
156 // ignore prio, for removal, only the handler ptr matters
157 return mpHandler == rRHS.mpHandler;
158 }
159};
160
161}
162
164 awt::XMouseListener,
165 awt::XMouseMotionListener > Listener_UnoBase;
166
167namespace {
168
175class EventMultiplexerListener : public Listener_UnoBase
176{
177public:
178 EventMultiplexerListener( EventQueue& rEventQueue,
179 EventMultiplexerImpl& rEventMultiplexer ) :
180 mpEventQueue( &rEventQueue ),
181 mpEventMultiplexer( &rEventMultiplexer )
182 {
183 }
184
185 EventMultiplexerListener( const EventMultiplexerListener& ) = delete;
186 EventMultiplexerListener& operator=( const EventMultiplexerListener& ) = delete;
187
188 // WeakComponentImplHelperBase::disposing
189 virtual void disposing(std::unique_lock<std::mutex>& rGuard) override;
190
191private:
192 virtual void SAL_CALL disposing( const lang::EventObject& Source ) override;
193
194 // XMouseListener implementation
195 virtual void SAL_CALL mousePressed( const awt::MouseEvent& e ) override;
196 virtual void SAL_CALL mouseReleased( const awt::MouseEvent& e ) override;
197 virtual void SAL_CALL mouseEntered( const awt::MouseEvent& e ) override;
198 virtual void SAL_CALL mouseExited( const awt::MouseEvent& e ) override;
199
200 // XMouseMotionListener implementation
201 virtual void SAL_CALL mouseDragged( const awt::MouseEvent& e ) override;
202 virtual void SAL_CALL mouseMoved( const awt::MouseEvent& e ) override;
203
204
205 EventQueue* mpEventQueue;
206 EventMultiplexerImpl* mpEventMultiplexer;
207};
208
209}
210
212{
214 UnoViewContainer const& rViewContainer ) :
215 mrEventQueue(rEventQueue),
216 mrViewContainer(rViewContainer),
217 mxListener( new EventMultiplexerListener(rEventQueue,
218 *this) ),
236 mnTimeout(0.0),
237 mpTickEvent(),
238 mbIsAutoMode(false)
239 {}
240
242 {
243 if( mxListener.is() )
244 mxListener->dispose();
245 }
246
248 void clear();
249
250 // actual handler callbacks (get called from the UNO interface
251 // listeners via event queue)
252 void mousePressed( const awt::MouseEvent& e );
253 void mouseReleased( const awt::MouseEvent& e );
254 void mouseDragged( const awt::MouseEvent& e );
255 void mouseMoved( const awt::MouseEvent& e );
256
257 bool isMouseListenerRegistered() const;
258
260 PrioritizedHandlerEntry<EventHandler>,
261 std::vector<
262 PrioritizedHandlerEntry<EventHandler> > > ImplNextEffectHandlers;
263 typedef PrioritizedHandlerEntry<MouseEventHandler> ImplMouseHandlerEntry;
266 std::vector<ImplMouseHandlerEntry> > ImplMouseHandlers;
269 std::vector<EventHandlerSharedPtr> > ImplEventHandlers;
272 std::vector<AnimationEventHandlerSharedPtr> > ImplAnimationHandlers;
275 std::vector<PauseEventHandlerSharedPtr> > ImplPauseHandlers;
277 ViewEventHandlerWeakPtrWrapper,
278 std::vector<ViewEventHandlerWeakPtrWrapper> > ImplViewHandlers;
281 std::vector<ViewRepaintHandlerSharedPtr> > ImplRepaintHandlers;
284 std::vector<ShapeListenerEventHandlerSharedPtr> > ImplShapeListenerHandlers;
287 std::vector<UserPaintEventHandlerSharedPtr> > ImplUserPaintEventHandlers;
289 PrioritizedHandlerEntry<HyperlinkHandler>,
290 std::vector<PrioritizedHandlerEntry<HyperlinkHandler> > > ImplHyperLinkHandlers;
291
292 template <typename XSlideShowViewFunc>
293 void forEachView( XSlideShowViewFunc pViewMethod );
294
296 presentation::XSlideShowView>& xView) const;
297
298 template< typename RegisterFunction >
299 void addMouseHandler( ImplMouseHandlers& rHandlerContainer,
300 const MouseEventHandlerSharedPtr& rHandler,
301 double nPriority,
302 RegisterFunction pRegisterListener );
303
304 static bool notifyAllAnimationHandlers( ImplAnimationHandlers const& rContainer,
305 AnimationNodeSharedPtr const& rNode );
306
308 const ImplMouseHandlers& rQueue,
309 bool (MouseEventHandler::*pHandlerMethod)(
310 const awt::MouseEvent& ),
311 const awt::MouseEvent& e );
312
313 bool notifyNextEffect();
314
316 void tick();
317
319 void scheduleTick();
320
322 void handleTicks();
323
328
332 EventMultiplexerListener> mxListener;
333
351
353 double mnTimeout;
354
361 ::std::weak_ptr< Event > mpTickEvent;
363};
364
365
366void EventMultiplexerListener::disposing(std::unique_lock<std::mutex>& /*rGuard*/)
367{
368 mpEventQueue = nullptr;
369 mpEventMultiplexer = nullptr;
370}
371
372void SAL_CALL EventMultiplexerListener::disposing(
373 const lang::EventObject& /*rSource*/ )
374{
375 // there's no real point in acting on this message - after all,
376 // the event sources are the XSlideShowViews, which must be
377 // explicitly removed from the slideshow via
378 // XSlideShow::removeView(). thus, if a XSlideShowView has
379 // properly removed itself from the slideshow, it will not be
380 // found here. and if it hasn't, there'll be other references at
381 // other places within the slideshow, anyway...
382}
383
384void SAL_CALL EventMultiplexerListener::mousePressed(
385 const awt::MouseEvent& e )
386{
387 std::unique_lock const guard( m_aMutex );
388
389 // notify mouse press. Don't call handlers directly, this
390 // might not be the main thread!
391 if( mpEventQueue )
395 e ),
396 "EventMultiplexerImpl::mousePressed") );
397}
398
399void SAL_CALL EventMultiplexerListener::mouseReleased(
400 const awt::MouseEvent& e )
401{
402 std::unique_lock const guard( m_aMutex );
403
404 // notify mouse release. Don't call handlers directly,
405 // this might not be the main thread!
406 if( mpEventQueue )
410 e ),
411 "EventMultiplexerImpl::mouseReleased") );
412}
413
414void SAL_CALL EventMultiplexerListener::mouseEntered(
415 const awt::MouseEvent& /*e*/ )
416{
417 // not used here
418}
419
420void SAL_CALL EventMultiplexerListener::mouseExited(
421 const awt::MouseEvent& /*e*/ )
422{
423 // not used here
424}
425
426// XMouseMotionListener implementation
427void SAL_CALL EventMultiplexerListener::mouseDragged(
428 const awt::MouseEvent& e )
429{
430 std::unique_lock const guard( m_aMutex );
431
432 // notify mouse drag. Don't call handlers directly, this
433 // might not be the main thread!
434 if( mpEventQueue )
438 e ),
439 "EventMultiplexerImpl::mouseDragged") );
440}
441
442void SAL_CALL EventMultiplexerListener::mouseMoved(
443 const awt::MouseEvent& e )
444{
445 std::unique_lock const guard( m_aMutex );
446
447 // notify mouse move. Don't call handlers directly, this
448 // might not be the main thread!
449 if( mpEventQueue )
453 e ),
454 "EventMultiplexerImpl::mouseMoved") );
455}
456
457
459 AnimationNodeSharedPtr const& rNode )
460{
461 return rContainer.applyAll(
462 [&rNode]( const AnimationEventHandlerSharedPtr& pEventHandler )
463 { return pEventHandler->handleAnimationEvent( rNode ); } );
464}
465
466template <typename XSlideShowViewFunc>
467void EventMultiplexerImpl::forEachView( XSlideShowViewFunc pViewMethod )
468{
469 if( !pViewMethod )
470 return;
471
472 // (un)register mouse listener on all views
473 for( UnoViewVector::const_iterator aIter( mrViewContainer.begin() ),
474 aEnd( mrViewContainer.end() ); aIter != aEnd; ++aIter )
475 {
476 uno::Reference<presentation::XSlideShowView> xView ((*aIter)->getUnoView());
477 if (xView.is())
478 {
479 (xView.get()->*pViewMethod)( mxListener.get() );
480 }
481 else
482 {
483 OSL_ASSERT(xView.is());
484 }
485 }
486}
487
490{
491 // find view from which the change originated
492 UnoViewVector::const_iterator aIter;
493 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
494 if( (aIter=std::find_if( mrViewContainer.begin(),
495 aEnd,
496 [&xView]( const UnoViewSharedPtr& pView )
497 { return xView == pView->getUnoView(); } )) == aEnd )
498 {
499 OSL_FAIL("EventMultiplexer::findUnoView(): unexpected message source" );
500 return UnoViewSharedPtr();
501 }
502
503 return *aIter;
504}
505
506template< typename RegisterFunction >
508 ImplMouseHandlers& rHandlerContainer,
509 const MouseEventHandlerSharedPtr& rHandler,
510 double nPriority,
511 RegisterFunction pRegisterListener )
512{
514 rHandler,
515 "EventMultiplexer::addMouseHandler(): Invalid handler" );
516
517 // register mouse listener on all views
518 forEachView( pRegisterListener );
519
520 // add into sorted container:
521 rHandlerContainer.addSorted(
522 typename ImplMouseHandlers::container_type::value_type(
523 rHandler,
524 nPriority ));
525}
526
528{
529 return !(maMouseClickHandlers.isEmpty() &&
531}
532
534{
535 if( !mbIsAutoMode )
536 return; // this event is just a left-over, ignore
537
539
541 {
542 // still handlers left, schedule next timeout
543 // event. Will also set mbIsTickEventOn back to true
544 scheduleTick();
545 }
546}
547
549{
550 EventSharedPtr pEvent(
551 makeDelay( [this] () { this->tick(); },
552 mnTimeout,
553 "EventMultiplexerImpl::tick with delay"));
554
555 // store weak reference to generated event, to notice when
556 // the event queue gets cleansed (we then have to
557 // regenerate the tick event!)
558 mpTickEvent = pEvent;
559
560 // enabled auto mode: simply schedule a timeout event,
561 // which will eventually call our tick() method
563}
564
566{
567 if( !mbIsAutoMode )
568 return; // nothing to do, don't need no ticks
569
570 EventSharedPtr pTickEvent( mpTickEvent.lock() );
571 if( pTickEvent )
572 return; // nothing to do, there's already a tick
573 // pending
574
575 // schedule initial tick (which reschedules itself
576 // after that, all by itself)
577 scheduleTick();
578}
579
583{
584 UnoViewVector::const_iterator aIter;
585 const UnoViewVector::const_iterator aEnd(mrViewContainer.end());
586 if ((aIter = std::find_if(
587 mrViewContainer.begin(), aEnd,
588 [&xView](const UnoViewSharedPtr& pView) { return xView == pView->getUnoView(); }))
589 == aEnd)
590 {
591 return pnt;
592 }
593
594 basegfx::B2DPoint aPosition(pnt.getX(), pnt.getY());
595 basegfx::B2DHomMatrix aMatrix((*aIter)->getTransformation());
596 aPosition *= aMatrix;
597
598 aPosition.setX(basegfx::fround(aPosition.getX()));
599 aPosition.setY(basegfx::fround(aPosition.getY()));
600 return aPosition;
601}
602
606{
607 UnoViewVector::const_iterator aIter;
608 const UnoViewVector::const_iterator aEnd(mrViewContainer.end());
609 if ((aIter = std::find_if(
610 mrViewContainer.begin(), aEnd,
611 [&xView](const UnoViewSharedPtr& pView) { return xView == pView->getUnoView(); }))
612 == aEnd)
613 {
614 return pnt;
615 }
616
617 basegfx::B2DPoint aPosition(pnt.getX(), pnt.getY());
618 basegfx::B2DHomMatrix aMatrix((*aIter)->getTransformation());
619 if (!aMatrix.invert())
620 ENSURE_OR_THROW(false, "EventMultiplexer::notifyHandlers():"
621 " view matrix singular");
622 aPosition *= aMatrix;
623
624 aPosition.setX(basegfx::fround(aPosition.getX()));
625 aPosition.setY(basegfx::fround(aPosition.getY()));
626 return aPosition;
627}
628
630{
631 // deregister from all views.
633 {
634 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
635 aEnd=mrViewContainer.end();
636 aIter!=aEnd;
637 ++aIter )
638 {
639 if( (*aIter)->getUnoView().is() )
640 (*aIter)->getUnoView()->removeMouseListener( mxListener );
641 }
642 }
643
645 {
646 for( UnoViewVector::const_iterator aIter=mrViewContainer.begin(),
647 aEnd=mrViewContainer.end();
648 aIter!=aEnd;
649 ++aIter )
650 {
651 if( (*aIter)->getUnoView().is() )
652 (*aIter)->getUnoView()->removeMouseMotionListener( mxListener );
653 }
654 }
655
656 // clear all handlers (releases all references)
672 mpTickEvent.reset();
673}
674
675// XMouseListener implementation
677 const ImplMouseHandlers& rQueue,
678 bool (MouseEventHandler::*pHandlerMethod)( const awt::MouseEvent& ),
679 const awt::MouseEvent& e )
680{
682 e.Source, uno::UNO_QUERY );
683
684 ENSURE_OR_RETURN_FALSE( xView.is(), "EventMultiplexer::notifyHandlers(): "
685 "event source is not an XSlideShowView" );
686
687 // find corresponding view (to map mouse position into user
688 // coordinate space)
689 UnoViewVector::const_iterator aIter;
690 const UnoViewVector::const_iterator aEnd ( mrViewContainer.end() );
691 if( (aIter=::std::find_if(
693 aEnd,
694 [&xView]( const UnoViewSharedPtr& pView )
695 { return xView == pView->getUnoView(); } )) == aEnd )
696 {
698 false, "EventMultiplexer::notifyHandlers(): "
699 "event source not found under registered views" );
700 }
701
702 // convert mouse position to user coordinate space
703 ::basegfx::B2DPoint aPosition( e.X, e.Y );
704 ::basegfx::B2DHomMatrix aMatrix( (*aIter)->getTransformation() );
705 if( !aMatrix.invert() )
706 ENSURE_OR_THROW( false, "EventMultiplexer::notifyHandlers():"
707 " view matrix singular" );
708 aPosition *= aMatrix;
709
710 awt::MouseEvent aEvent( e );
711 aEvent.X = ::basegfx::fround( aPosition.getX() );
712 aEvent.Y = ::basegfx::fround( aPosition.getY() );
713
714 // fire event on handlers, try in order of precedence. If
715 // one high-priority handler rejects the event
716 // (i.e. returns false), try next handler.
717 return rQueue.apply(
718 [&pHandlerMethod, &aEvent]( const ImplMouseHandlerEntry& rMouseHandler )
719 { return ( ( *rMouseHandler.getHandler() ).*pHandlerMethod )( aEvent ); } );
720}
721
722void EventMultiplexerImpl::mousePressed( const awt::MouseEvent& e )
723{
724 // fire double-click events for every second click
725 sal_Int32 nCurrClickCount = e.ClickCount;
726 while( nCurrClickCount > 1 &&
729 e ))
730 {
731 nCurrClickCount -= 2;
732 }
733
734 // fire single-click events for all remaining clicks
735 while( nCurrClickCount > 0 &&
738 e ))
739 {
740 --nCurrClickCount;
741 }
742}
743
744void EventMultiplexerImpl::mouseReleased( const awt::MouseEvent& e )
745{
746 // fire double-click events for every second click
747 sal_Int32 nCurrClickCount = e.ClickCount;
748 while( nCurrClickCount > 1 &&
751 e ))
752 {
753 nCurrClickCount -= 2;
754 }
755
756 // fire single-click events for all remaining clicks
757 while( nCurrClickCount > 0 &&
760 e ))
761 {
762 --nCurrClickCount;
763 }
764}
765
766void EventMultiplexerImpl::mouseDragged( const awt::MouseEvent& e )
767{
770 e );
771}
772
773void EventMultiplexerImpl::mouseMoved( const awt::MouseEvent& e )
774{
777 e );
778}
779
781{
782 // fire event on handlers, try in order of precedence. If one
783 // high-priority handler rejects the event (i.e. returns false),
784 // try next handler.
786 []( const PrioritizedHandlerEntry< EventHandler >& pHandler )
787 { return pHandler.getHandler()->handleEvent(); } );
788}
789
790
792 UnoViewContainer const& rViewContainer ) :
793 mpImpl( new EventMultiplexerImpl(rEventQueue, rViewContainer) )
794{
795}
796
798{
799 // outline because of EventMultiplexerImpl's incomplete type
800}
801
803{
804 mpImpl->clear();
805}
806
808{
809 if( bIsAuto == mpImpl->mbIsAutoMode )
810 return; // no change, nothing to do
811
812 mpImpl->mbIsAutoMode = bIsAuto;
813
814 mpImpl->handleTicks();
815}
816
818{
819 return mpImpl->mbIsAutoMode;
820}
821
823{
824 mpImpl->mnTimeout = nTimeout;
825}
826
828{
829 return mpImpl->mnTimeout;
830}
831
833 EventHandlerSharedPtr const& rHandler,
834 double nPriority )
835{
836 mpImpl->maNextEffectHandlers.addSorted(
837 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
838 rHandler,
839 nPriority) );
840
841 // Enable tick events, if not done already
842 mpImpl->handleTicks();
843}
844
846 const EventHandlerSharedPtr& rHandler )
847{
848 mpImpl->maNextEffectHandlers.remove(
849 EventMultiplexerImpl::ImplNextEffectHandlers::container_type::value_type(
850 rHandler,
851 0.0) );
852}
853
855 const EventHandlerSharedPtr& rHandler )
856{
857 mpImpl->maSlideStartHandlers.add( rHandler );
858}
859
861 const EventHandlerSharedPtr& rHandler )
862{
863 mpImpl->maSlideStartHandlers.remove( rHandler );
864}
865
867 const EventHandlerSharedPtr& rHandler )
868{
869 mpImpl->maSlideEndHandlers.add( rHandler );
870}
871
873 const EventHandlerSharedPtr& rHandler )
874{
875 mpImpl->maSlideEndHandlers.remove( rHandler );
876}
877
879 const AnimationEventHandlerSharedPtr& rHandler )
880{
881 mpImpl->maAnimationStartHandlers.add( rHandler );
882}
883
885 const AnimationEventHandlerSharedPtr& rHandler )
886{
887 mpImpl->maAnimationStartHandlers.remove( rHandler );
888}
889
891 const AnimationEventHandlerSharedPtr& rHandler )
892{
893 mpImpl->maAnimationEndHandlers.add( rHandler );
894}
895
897 const AnimationEventHandlerSharedPtr& rHandler )
898{
899 mpImpl->maAnimationEndHandlers.remove( rHandler );
900}
901
903 const EventHandlerSharedPtr& rHandler )
904{
905 mpImpl->maSlideAnimationsEndHandlers.add( rHandler );
906}
907
909 const EventHandlerSharedPtr& rHandler )
910{
911 mpImpl->maSlideAnimationsEndHandlers.remove( rHandler );
912}
913
915 const AnimationEventHandlerSharedPtr& rHandler )
916{
917 mpImpl->maAudioStoppedHandlers.add( rHandler );
918}
919
921 const AnimationEventHandlerSharedPtr& rHandler )
922{
923 mpImpl->maAudioStoppedHandlers.remove( rHandler );
924}
925
927 const AnimationEventHandlerSharedPtr& rHandler )
928{
929 mpImpl->maCommandStopAudioHandlers.add( rHandler );
930}
931
933 const AnimationEventHandlerSharedPtr& rHandler )
934{
935 mpImpl->maCommandStopAudioHandlers.remove( rHandler );
936}
937
939 const PauseEventHandlerSharedPtr& rHandler )
940{
941 mpImpl->maPauseHandlers.add( rHandler );
942}
943
945 const PauseEventHandlerSharedPtr& rHandler )
946{
947 mpImpl->maPauseHandlers.remove( rHandler );
948}
949
951 const ViewEventHandlerWeakPtr& rHandler )
952{
953 mpImpl->maViewHandlers.add( rHandler );
954}
955
957{
958 mpImpl->maViewHandlers.remove( rHandler );
959}
960
962{
963 mpImpl->maViewRepaintHandlers.add( rHandler );
964}
965
967{
968 mpImpl->maViewRepaintHandlers.remove( rHandler );
969}
970
972{
973 mpImpl->maShapeListenerHandlers.add( rHandler );
974}
975
977{
978 mpImpl->maShapeListenerHandlers.remove( rHandler );
979}
980
982{
983 mpImpl->maUserPaintEventHandlers.add( rHandler );
984}
985
987 const MouseEventHandlerSharedPtr& rHandler,
988 double nPriority )
989{
990 mpImpl->addMouseHandler(
991 mpImpl->maMouseClickHandlers,
992 rHandler,
993 nPriority,
994 mpImpl->isMouseListenerRegistered()
995 ? nullptr
996 : &presentation::XSlideShowView::addMouseListener );
997}
998
1000 const MouseEventHandlerSharedPtr& rHandler )
1001{
1002 mpImpl->maMouseClickHandlers.remove(
1003 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
1004 rHandler,
1005 0.0) );
1006
1007 if( !mpImpl->isMouseListenerRegistered() )
1008 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
1009}
1010
1012 const MouseEventHandlerSharedPtr& rHandler,
1013 double nPriority )
1014{
1015 mpImpl->addMouseHandler(
1016 mpImpl->maMouseDoubleClickHandlers,
1017 rHandler,
1018 nPriority,
1019 mpImpl->isMouseListenerRegistered()
1020 ? nullptr
1021 : &presentation::XSlideShowView::addMouseListener );
1022}
1023
1025 const MouseEventHandlerSharedPtr& rHandler )
1026{
1027 mpImpl->maMouseDoubleClickHandlers.remove(
1028 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
1029 rHandler,
1030 0.0) );
1031
1032 if( !mpImpl->isMouseListenerRegistered() )
1033 mpImpl->forEachView( &presentation::XSlideShowView::removeMouseListener );
1034}
1035
1037 const MouseEventHandlerSharedPtr& rHandler,
1038 double nPriority )
1039{
1040 mpImpl->addMouseHandler(
1041 mpImpl->maMouseMoveHandlers,
1042 rHandler,
1043 nPriority,
1044 mpImpl->maMouseMoveHandlers.isEmpty()
1045 ? &presentation::XSlideShowView::addMouseMotionListener
1046 : nullptr );
1047}
1048
1050 const MouseEventHandlerSharedPtr& rHandler )
1051{
1052 mpImpl->maMouseMoveHandlers.remove(
1053 EventMultiplexerImpl::ImplMouseHandlers::container_type::value_type(
1054 rHandler,
1055 0.0) );
1056
1057 if( mpImpl->maMouseMoveHandlers.isEmpty() )
1058 mpImpl->forEachView(
1059 &presentation::XSlideShowView::removeMouseMotionListener );
1060}
1061
1063 double nPriority )
1064{
1065 mpImpl->maHyperlinkHandlers.addSorted(
1066 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
1067 rHandler,
1068 nPriority) );
1069}
1070
1072{
1073 mpImpl->maHyperlinkHandlers.remove(
1074 EventMultiplexerImpl::ImplHyperLinkHandlers::container_type::value_type(
1075 rHandler,
1076 0.0) );
1077}
1078
1080 const uno::Reference<drawing::XShape>& xShape )
1081{
1082 mpImpl->maShapeListenerHandlers.applyAll(
1083 [&xShape]( const ShapeListenerEventHandlerSharedPtr& pHandler )
1084 { return pHandler->listenerAdded( xShape ); } );
1085}
1086
1088 const uno::Reference<drawing::XShape>& xShape )
1089{
1090 mpImpl->maShapeListenerHandlers.applyAll(
1091 [&xShape]( const ShapeListenerEventHandlerSharedPtr& pHandler )
1092 { return pHandler->listenerRemoved( xShape ); } );
1093}
1094
1096{
1097 mpImpl->maUserPaintEventHandlers.applyAll(
1098 [&rUserColor]( const UserPaintEventHandlerSharedPtr& pHandler )
1099 { return pHandler->colorChanged( rUserColor ); } );
1100}
1101
1103{
1104 mpImpl->maUserPaintEventHandlers.applyAll(
1105 [&rUserStrokeWidth]( const UserPaintEventHandlerSharedPtr& pHandler )
1106 { return pHandler->widthChanged( rUserStrokeWidth ); } );
1107}
1108
1110{
1111 mpImpl->maUserPaintEventHandlers.applyAll(
1112 std::mem_fn(&UserPaintEventHandler::disable));
1113}
1114
1116 mpImpl->maUserPaintEventHandlers.applyAll(
1118}
1119
1121 mpImpl->maUserPaintEventHandlers.applyAll(
1123}
1124
1125//adding erasing all ink features with UserPaintOverlay
1127{
1128 mpImpl->maUserPaintEventHandlers.applyAll(
1129 [&bEraseAllInk]( const UserPaintEventHandlerSharedPtr& pHandler )
1130 { return pHandler->eraseAllInkChanged( bEraseAllInk ); } );
1131}
1132
1133//adding erasing features with UserPaintOverlay
1134void EventMultiplexer::notifyEraseInkWidth( sal_Int32 rEraseInkSize )
1135{
1136 mpImpl->maUserPaintEventHandlers.applyAll(
1137 [&rEraseInkSize]( const UserPaintEventHandlerSharedPtr& pHandler )
1138 { return pHandler->eraseInkWidthChanged( rEraseInkSize ); } );
1139}
1140
1142{
1143 return mpImpl->notifyNextEffect();
1144}
1145
1147{
1148 mpImpl->maSlideStartHandlers.applyAll(
1149 std::mem_fn(&EventHandler::handleEvent) );
1150}
1151
1153{
1154 return mpImpl->maSlideEndHandlers.applyAll(
1155 std::mem_fn(&EventHandler::handleEvent) );
1156}
1157
1159 const AnimationNodeSharedPtr& rNode )
1160{
1161 return EventMultiplexerImpl::notifyAllAnimationHandlers( mpImpl->maAnimationStartHandlers,
1162 rNode );
1163}
1164
1166 const AnimationNodeSharedPtr& rNode )
1167{
1168 return EventMultiplexerImpl::notifyAllAnimationHandlers( mpImpl->maAnimationEndHandlers,
1169 rNode );
1170}
1171
1173{
1174 return mpImpl->maSlideAnimationsEndHandlers.applyAll(
1175 std::mem_fn(&EventHandler::handleEvent));
1176}
1177
1179 const AnimationNodeSharedPtr& rNode )
1180{
1182 mpImpl->maAudioStoppedHandlers,
1183 rNode );
1184}
1185
1187 const AnimationNodeSharedPtr& rNode )
1188{
1190 mpImpl->maCommandStopAudioHandlers,
1191 rNode );
1192}
1193
1195{
1196 mpImpl->maPauseHandlers.applyAll(
1197 [&bPauseShow]( const PauseEventHandlerSharedPtr& pHandler )
1198 { return pHandler->handlePause( bPauseShow ); } );
1199}
1200
1202{
1203 ENSURE_OR_THROW( rView, "EventMultiplexer::notifyViewAdded(): Invalid view");
1204
1205 // register event listener
1207 rView->getUnoView() );
1208
1209 if( mpImpl->isMouseListenerRegistered() )
1210 rUnoView->addMouseListener(
1211 mpImpl->mxListener );
1212
1213 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1214 rUnoView->addMouseMotionListener(
1215 mpImpl->mxListener );
1216
1217 mpImpl->maViewHandlers.applyAll(
1218 [&rView]( const ViewEventHandlerWeakPtr& pHandler )
1219 { return pHandler.lock()->viewAdded( rView ); } );
1220}
1221
1223{
1224 ENSURE_OR_THROW( rView,
1225 "EventMultiplexer::removeView(): Invalid view" );
1226
1227 // revoke event listeners
1229 rView->getUnoView() );
1230
1231 if( mpImpl->isMouseListenerRegistered() )
1232 rUnoView->removeMouseListener(
1233 mpImpl->mxListener );
1234
1235 if( !mpImpl->maMouseMoveHandlers.isEmpty() )
1236 rUnoView->removeMouseMotionListener(
1237 mpImpl->mxListener );
1238
1239 mpImpl->maViewHandlers.applyAll(
1240 [&rView]( const ViewEventHandlerWeakPtr& pHandler )
1241 { return pHandler.lock()->viewRemoved( rView ); } );
1242}
1243
1245{
1246 mpImpl->maViewHandlers.applyAll(
1247 [&rView]( const ViewEventHandlerWeakPtr& pHandler )
1248 { return pHandler.lock()->viewChanged( rView ); } );
1249}
1250
1252{
1253 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1254
1255 if( !pView )
1256 return; // view not registered here
1257
1258 notifyViewChanged( pView );
1259}
1260
1262{
1263 mpImpl->maViewHandlers.applyAll(
1264 std::mem_fn( &ViewEventHandler::viewsChanged ));
1265}
1266
1269{
1270 UnoViewSharedPtr pView( mpImpl->findUnoView(xView) );
1271
1272 if( !pView )
1273 return; // view not registered here
1274
1275 mpImpl->maViewRepaintHandlers.applyAll(
1276 [&pView]( const ViewRepaintHandlerSharedPtr& pHandler )
1277 { return pHandler->viewClobbered( pView ); } );
1278}
1279
1281 OUString const& hyperLink )
1282{
1283 mpImpl->maHyperlinkHandlers.apply(
1284 [&hyperLink]( const PrioritizedHandlerEntry< HyperlinkHandler >& pHandler )
1285 { return pHandler.getHandler()->handleHyperlink( hyperLink ); } );
1286}
1287
1290{
1291 uno::Reference<presentation::XSlideShowView> xView(xInterface, uno::UNO_QUERY_THROW);
1292 return mpImpl->toMatrixPoint(xView, pnt);
1293}
1294
1297{
1298 uno::Reference<presentation::XSlideShowView> xView(xInterface, uno::UNO_QUERY_THROW);
1299 return mpImpl->toNormalPoint(xView, pnt);
1300}
1301
1302} // namespace presentation
1303
1304/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
TYPE getX() const
void setY(TYPE fY)
TYPE getY() const
void setX(TYPE fX)
virtual bool handleEvent()=0
Handle the event.
void removeClickHandler(const MouseEventHandlerSharedPtr &rHandler)
void setAutomaticTimeout(double nTimeout)
Set the timeout for automatic mode.
void notifyViewChanged(const UnoViewSharedPtr &rView)
View changed.
void addAnimationStartHandler(const AnimationEventHandlerSharedPtr &rHandler)
Register an event handler that will be called when an XAnimationNode starts its active duration.
void addHyperlinkHandler(const HyperlinkHandlerSharedPtr &rHandler, double nPriority)
Registers a hyperlink click handler.
bool notifyAudioStopped(const AnimationNodeSharedPtr &rNode)
Notify that for the given node, audio output has stopped.
void removeMouseMoveHandler(const MouseEventHandlerSharedPtr &rHandler)
void notifyViewRemoved(const UnoViewSharedPtr &rView)
View removed.
double getAutomaticTimeout() const
Get automatic mode timeout value.
void addClickHandler(const MouseEventHandlerSharedPtr &rHandler, double nPriority)
Register a mouse handler that is called on mouse click.
void addMouseMoveHandler(const MouseEventHandlerSharedPtr &rHandler, double nPriority)
Register a mouse handler that is called for mouse moves.
void removeSlideAnimationsEndHandler(const EventHandlerSharedPtr &rHandler)
void addCommandStopAudioHandler(const AnimationEventHandlerSharedPtr &rHandler)
Register an event handler that will be called when an XCommand node's with the command STOPAUDIO is a...
void removeAnimationEndHandler(const AnimationEventHandlerSharedPtr &rHandler)
EventMultiplexer(EventQueue &rEventQueue, UnoViewContainer const &rViewContainer)
Create an event multiplexer.
void notifyUserPaintStrokeWidth(double rUserStrokeWidth)
Notify a new user paint width.
void clear()
Clear all registered handlers.
void removeSlideEndHandler(const EventHandlerSharedPtr &rHandler)
void removeViewRepaintHandler(const ViewRepaintHandlerSharedPtr &rHandler)
void removeViewHandler(const ViewEventHandlerWeakPtr &rHandler)
void removePauseHandler(const PauseEventHandlerSharedPtr &rHandler)
void addSlideEndHandler(const EventHandlerSharedPtr &rHandler)
Register an event handler that will be called when the slide is about to vanish.
void notifyUserPaintColor(RGBColor const &rUserColor)
Notify a new user paint color.
void addSlideStartHandler(const EventHandlerSharedPtr &rHandler)
Register an event handler that will be called when the slide is just shown.
void notifyEraseAllInk(bool bEraseAllInk)
Notify a new user paint erase all ink mode.
basegfx::B2DPoint toNormalPoint(css::uno::Reference< css::uno::XInterface > xInterface, basegfx::B2DPoint pnt)
void addSlideAnimationsEndHandler(const EventHandlerSharedPtr &rHandler)
Register an event handler that will be called when the main animation sequence of a slide ends its ac...
void removeAudioStoppedHandler(const AnimationEventHandlerSharedPtr &rHandler)
bool notifyAnimationStart(const AnimationNodeSharedPtr &rNode)
Notify that the given node enters its active duration.
void notifyPauseMode(bool bPauseShow)
Notify that the show has entered or exited pause mode.
void notifyUserPaintDisabled()
Notify that user paint is disabled.
void removeDoubleClickHandler(const MouseEventHandlerSharedPtr &rHandler)
void notifyViewAdded(const UnoViewSharedPtr &rView)
View added.
bool notifyCommandStopAudio(const AnimationNodeSharedPtr &rNode)
Notify that all audio has to be stopped.
bool getAutomaticMode() const
Get automatic mode setting.
bool notifySlideEndEvent()
Notify that a slide has ended.
void notifySlideStartEvent()
Notify that a new slide has started.
void addViewHandler(const ViewEventHandlerWeakPtr &rHandler)
Register an event handler that will be called when views are changed.
std::unique_ptr< EventMultiplexerImpl > mpImpl
void addNextEffectHandler(const EventHandlerSharedPtr &rHandler, double nPriority)
Register an event handler that will be called when the user requests the next effect.
bool notifyNextEffect()
Notify that the user requested the next effect.
void notifyViewClobbered(const css::uno::Reference< css::presentation::XSlideShowView > &xView)
View clobbered.
void addPauseHandler(const PauseEventHandlerSharedPtr &rHandler)
Register a handler that is called when the show enters or exits pause mode.
void notifyViewsChanged()
All Views changed.
void addDoubleClickHandler(const MouseEventHandlerSharedPtr &rHandler, double nPriority)
Register a mouse handler that is called on a double mouse click.
void removeSlideStartHandler(const EventHandlerSharedPtr &rHandler)
basegfx::B2DPoint toMatrixPoint(css::uno::Reference< css::uno::XInterface > xInterface, basegfx::B2DPoint pnt)
void removeNextEffectHandler(const EventHandlerSharedPtr &rHandler)
void addViewRepaintHandler(const ViewRepaintHandlerSharedPtr &rHandler)
Register an event handler that will be called when a view gets clobbered.
void addAnimationEndHandler(const AnimationEventHandlerSharedPtr &rHandler)
Register an event handler that will be called when an XAnimationNode ends its active duration.
void notifyEraseInkWidth(sal_Int32 rEraseInkSize)
void notifyShapeListenerAdded(const css::uno::Reference< css::drawing::XShape > &xShape)
New shape event listener added.
bool notifySlideAnimationsEnd()
Notify that the slide animations sequence leaves its active duration.
void addShapeListenerHandler(const ShapeListenerEventHandlerSharedPtr &rHandler)
Register an event handler that will be called when XShapeListeners are changed.
void removeHyperlinkHandler(const HyperlinkHandlerSharedPtr &rHandler)
void notifyShapeListenerRemoved(const css::uno::Reference< css::drawing::XShape > &xShape)
A shape event listener was removed.
void removeShapeListenerHandler(const ShapeListenerEventHandlerSharedPtr &rHandler)
void setAutomaticMode(bool bIsAuto)
Change automatic mode.
void removeAnimationStartHandler(const AnimationEventHandlerSharedPtr &rHandler)
void removeCommandStopAudioHandler(const AnimationEventHandlerSharedPtr &rHandler)
void addAudioStoppedHandler(const AnimationEventHandlerSharedPtr &rHandler)
Register an event handler that will be called when an XAudio node's sound stops playing.
void notifyHyperlinkClicked(OUString const &hyperLink)
Notifies that a hyperlink has been clicked.
bool notifyAnimationEnd(const AnimationNodeSharedPtr &rNode)
Notify that the given node leaves its active duration.
void addUserPaintHandler(const UserPaintEventHandlerSharedPtr &rHandler)
Register an event handler that will be called when user paint parameters change.
This class handles events in a presentation.
Definition: eventqueue.hxx:41
bool addEventForNextRound(const EventSharedPtr &event)
Add the given event to the queue.
Definition: eventqueue.cxx:105
bool addEvent(const EventSharedPtr &event)
Add the given event to the queue.
Definition: eventqueue.cxx:79
bool apply(FuncT func) const
Apply functor to one listener.
bool isEmpty() const
Check whether listener container is empty.
bool applyAll(FuncT func) const
Apply functor to all listeners.
bool addSorted(listener_type const &rListener)
Add new listener into sorted container.
void clear()
Removes all listeners in one go.
Interface for handling mouse events.
virtual bool handleMouseDragged(const css::awt::MouseEvent &e)=0
Handle a mouse was moved with a pressed button event.
virtual bool handleMousePressed(const css::awt::MouseEvent &e)=0
Handle a mouse button pressed event.
virtual bool handleMouseMoved(const css::awt::MouseEvent &e)=0
Handle a mouse was moved event.
virtual bool handleMouseReleased(const css::awt::MouseEvent &e)=0
Handle a mouse button released event.
RGB color space class.
Definition: rgbcolor.hxx:35
ListenerContainer variant that does not serialize access.
virtual void viewsChanged()=0
Notify that all views changed.
#define makeEvent(f, d)
Definition: delayevent.hxx:131
#define makeDelay(f, t, d)
Definition: delayevent.hxx:128
#define ENSURE_OR_RETURN_FALSE(c, m)
#define ENSURE_OR_THROW(c, m)
double mnPrio
EventMultiplexerImpl * mpEventMultiplexer
EventQueue * mpEventQueue
HandlerSharedPtrT mpHandler
void SAL_CALL mouseReleased(const css::awt::MouseEvent &e) override
void SAL_CALL mouseExited(const css::awt::MouseEvent &e) override
void SAL_CALL mouseMoved(const css::awt::MouseEvent &e) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL mousePressed(const css::awt::MouseEvent &e) override
void SAL_CALL mouseEntered(const css::awt::MouseEvent &e) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL mouseDragged(const css::awt::MouseEvent &e) override
B2IRange fround(const B2DRange &rRange)
::std::weak_ptr< ViewEventHandler > ViewEventHandlerWeakPtr
bool operator==(const HSLColor &rLHS, const HSLColor &rRHS)
Definition: color.cxx:189
::std::shared_ptr< EventHandler > EventHandlerSharedPtr
comphelper::WeakComponentImplHelper< awt::XMouseListener, awt::XMouseMotionListener > Listener_UnoBase
::std::shared_ptr< MouseEventHandler > MouseEventHandlerSharedPtr
::std::shared_ptr< PauseEventHandler > PauseEventHandlerSharedPtr
::std::shared_ptr< ShapeListenerEventHandler > ShapeListenerEventHandlerSharedPtr
::std::shared_ptr< HyperlinkHandler > HyperlinkHandlerSharedPtr
::std::shared_ptr< UserPaintEventHandler > UserPaintEventHandlerSharedPtr
::std::shared_ptr< AnimationNode > AnimationNodeSharedPtr
::std::shared_ptr< Event > EventSharedPtr
Definition: event.hxx:76
::std::shared_ptr< ViewRepaintHandler > ViewRepaintHandlerSharedPtr
::std::shared_ptr< AnimationEventHandler > AnimationEventHandlerSharedPtr
std::shared_ptr< UnoView > UnoViewSharedPtr
ThreadUnsafeListenerContainer< PrioritizedHandlerEntry< HyperlinkHandler >, std::vector< PrioritizedHandlerEntry< HyperlinkHandler > > > ImplHyperLinkHandlers
::rtl::Reference< EventMultiplexerListener > mxListener
ThreadUnsafeListenerContainer< PrioritizedHandlerEntry< EventHandler >, std::vector< PrioritizedHandlerEntry< EventHandler > > > ImplNextEffectHandlers
void tick()
Called for automatic nextEffect.
void mousePressed(const awt::MouseEvent &e)
void addMouseHandler(ImplMouseHandlers &rHandlerContainer, const MouseEventHandlerSharedPtr &rHandler, double nPriority, RegisterFunction pRegisterListener)
void mouseMoved(const awt::MouseEvent &e)
void handleTicks()
Schedules tick events, if mbIsAutoMode is true.
ThreadUnsafeListenerContainer< UserPaintEventHandlerSharedPtr, std::vector< UserPaintEventHandlerSharedPtr > > ImplUserPaintEventHandlers
UnoViewSharedPtr findUnoView(const uno::Reference< presentation::XSlideShowView > &xView) const
basegfx::B2DPoint toNormalPoint(uno::Reference< presentation::XSlideShowView > xView, basegfx::B2DPoint pnt)
ThreadUnsafeListenerContainer< PauseEventHandlerSharedPtr, std::vector< PauseEventHandlerSharedPtr > > ImplPauseHandlers
void mouseReleased(const awt::MouseEvent &e)
ImplShapeListenerHandlers maShapeListenerHandlers
void forEachView(XSlideShowViewFunc pViewMethod)
bool notifyMouseHandlers(const ImplMouseHandlers &rQueue, bool(MouseEventHandler::*pHandlerMethod)(const awt::MouseEvent &), const awt::MouseEvent &e)
ThreadUnsafeListenerContainer< ViewRepaintHandlerSharedPtr, std::vector< ViewRepaintHandlerSharedPtr > > ImplRepaintHandlers
ThreadUnsafeListenerContainer< ViewEventHandlerWeakPtrWrapper, std::vector< ViewEventHandlerWeakPtrWrapper > > ImplViewHandlers
EventMultiplexerImpl(EventQueue &rEventQueue, UnoViewContainer const &rViewContainer)
ThreadUnsafeListenerContainer< AnimationEventHandlerSharedPtr, std::vector< AnimationEventHandlerSharedPtr > > ImplAnimationHandlers
void mouseDragged(const awt::MouseEvent &e)
static bool notifyAllAnimationHandlers(ImplAnimationHandlers const &rContainer, AnimationNodeSharedPtr const &rNode)
void scheduleTick()
Schedules a tick event.
ImplUserPaintEventHandlers maUserPaintEventHandlers
basegfx::B2DPoint toMatrixPoint(uno::Reference< presentation::XSlideShowView > xView, basegfx::B2DPoint pnt)
::std::weak_ptr< Event > mpTickEvent
Holds ptr to optional tick event weakly.
ThreadUnsafeListenerContainer< ShapeListenerEventHandlerSharedPtr, std::vector< ShapeListenerEventHandlerSharedPtr > > ImplShapeListenerHandlers
ThreadUnsafeListenerContainer< ImplMouseHandlerEntry, std::vector< ImplMouseHandlerEntry > > ImplMouseHandlers
PrioritizedHandlerEntry< MouseEventHandler > ImplMouseHandlerEntry
double mnTimeout
automatic next effect mode timeout
ThreadUnsafeListenerContainer< EventHandlerSharedPtr, std::vector< EventHandlerSharedPtr > > ImplEventHandlers
static void pruneListeners(ContainerT &rContainer, size_t nSizeThreshold)
static bool notifySingleListener(ContainerT &rContainer, FuncT func)
static bool notifyAllListeners(ContainerT &rContainer, FuncT func)
bool operator<(const wwFont &r1, const wwFont &r2)