1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef INCLUDED_SLIDESHOW_EVENTMULTIPLEXER_HXX
28 #define INCLUDED_SLIDESHOW_EVENTMULTIPLEXER_HXX
29 
30 #include "eventhandler.hxx"
31 #include "hyperlinkhandler.hxx"
32 #include "mouseeventhandler.hxx"
33 #include "animationeventhandler.hxx"
34 #include "pauseeventhandler.hxx"
35 #include "shapelistenereventhandler.hxx"
36 #include "shapecursoreventhandler.hxx"
37 #include "userpainteventhandler.hxx"
38 #include "vieweventhandler.hxx"
39 #include "viewrepainthandler.hxx"
40 
41 #include <boost/scoped_ptr.hpp>
42 #include <boost/noncopyable.hpp>
43 
44 
45 namespace slideshow {
46 namespace internal {
47 
48 class EventQueue;
49 class UnoViewContainer;
50 class AnimationNode;
51 
52 struct EventMultiplexerImpl;
53 
54 /** This class multiplexes user-activated and
55     slide-show global events.
56 
57     This class listens at the XSlideShowView and fires events
58     registered for certain user actions. Furthermore, global
59     slide show state changes (such as start or end of a slide)
60     are handled as well. Note that registered events which
61     have a non-zero timeout (i.e. events that return non-zero
62     from getActivationTime()) will not be fired immediately
63     after the user action occured, but only after the given
64     timeout. Which is actually a feature.
65 */
66 class EventMultiplexer : private ::boost::noncopyable
67 {
68 public:
69     /** Create an event multiplexer
70 
71         @param rEventQueue
72         Reference to the main event queue. Since we hold this
73         object by plain reference, it must live longer than we
74         do. On the other hand, that queue must not fire events
75         after this object is destroyed, since we might
76         schedule events there which itself contain plain
77         references to this object. Basically, EventQueue and
78         EventMultiplexer should have the same lifetime, and since
79         this is not possible, both must be destructed in a
80         phased mode: first clear both of any remaining events,
81         then destruct them.
82 
83         @param rViewContainer
84         Globally managed list of all registered views. Used to
85         determine event sources, and for registering view listeners
86         at.
87     */
88     EventMultiplexer( EventQueue&             rEventQueue,
89                       UnoViewContainer const& rViewContainer );
90     ~EventMultiplexer();
91 
92 
93     // Management methods
94     // =========================================================
95 
96     /** Clear all registered handlers.
97      */
98     void clear();
99 
100 
101     // Automatic mode methods
102     // =========================================================
103 
104     /** Change automatic mode.
105 
106         @param bIsAuto
107         When true, events will be fired automatically, not
108         only triggered by UI events. When false, auto events
109         will quit.
110     */
111     void setAutomaticMode( bool bIsAuto );
112 
113     /** Get automatic mode setting.
114      */
115     bool getAutomaticMode() const;
116 
117     /** Set the timeout for automatic mode.
118 
119         @param nTimeout
120         Timeout, between end of effect until start of next
121         effect.
122     */
123     void setAutomaticTimeout( double nTimeout );
124 
125     /** Get automatic mode timeout value.
126      */
127     double getAutomaticTimeout() const;
128 
129     // Handler registration methods
130     // =========================================================
131 
132     /** Register an event handler that will be called when views are
133         changed.
134 
135         For each view added, viewAdded() will be called on the
136         handler. For each view removed, viewRemoved() will be
137         called. Each modified view will cause a viewChanged() call on
138         each handler.
139 
140         You don't need to deregister the handler, it will be
141         automatically removed, once the pointee becomes stale.
142 
143         @param rHandler
144         Handler to call.
145     */
146     void addViewHandler( const ViewEventHandlerWeakPtr& rHandler );
147     void removeViewHandler( const ViewEventHandlerWeakPtr& rHandler );
148 
149     /** Register an event handler that will be called when a view gets
150         clobbered.
151 
152         Note that <em>all</em> registered handlers will be called when
153         the event. This is in contrast to the mouse events below.
154 
155         @param rHandler
156         Handler to call when a view needs a repaint
157     */
158     void addViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler );
159     void removeViewRepaintHandler( const ViewRepaintHandlerSharedPtr& rHandler );
160 
161     /** Register an event handler that will be called when
162         XShapeListeners are changed.
163 
164         @param rHandler
165         Handler to call when a shape listener changes
166     */
167     void addShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler );
168     void removeShapeListenerHandler( const ShapeListenerEventHandlerSharedPtr& rHandler );
169 
170     /** Register an event handler that will be called when
171         XShapeListeners are changed.
172 
173         @param rHandler
174         Handler to call when a shape listener changes
175     */
176     void addShapeCursorHandler( const ShapeCursorEventHandlerSharedPtr& rHandler );
177     void removeShapeCursorHandler( const ShapeCursorEventHandlerSharedPtr& rHandler );
178 
179     /** Register an event handler that will be called when
180         user paint parameters change.
181 
182         @param rHandler
183         Handler to call when a shape listener changes
184     */
185     void addUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler );
186     void removeUserPaintHandler( const UserPaintEventHandlerSharedPtr& rHandler );
187 
188     /** Register an event handler that will be called when the
189         user requests the next effect.
190 
191         For every nextEffect event, only one of the handlers
192         registered here is called. The handlers are considered
193         with decreasing priority, i.e. the handler with the
194         currently highest priority will be called.
195 
196         @param rHandler
197         Handler to call when the next effect should start
198 
199         @param nPriority
200         Priority with which the handlers are called. The
201         higher the priority, the earlier this handler will be
202         tried.
203     */
204     void addNextEffectHandler( const EventHandlerSharedPtr& rHandler,
205                                double                       nPriority );
206     void removeNextEffectHandler( const EventHandlerSharedPtr& rHandler );
207 
208     /** Register an event handler that will be called when the
209         slide is just shown.
210 
211         Note that <em>all</em> registered handlers will be called
212         when the slide start occurs. This is in contrast to
213         the mouse events below.
214 
215         @param rHandler
216         Handler to call when the next slide starts
217     */
218     void addSlideStartHandler( const EventHandlerSharedPtr& rHandler );
219     void removeSlideStartHandler( const EventHandlerSharedPtr& rHandler );
220 
221     /** Register an event handler that will be called when the
222         slide is about to vanish.
223 
224         Note that <em>all</em> registered handlers will be
225         called when the slide end occurs. This is in contrast
226         to the mouse events below.
227 
228         @param rHandler
229         Handler to call when the current slide ends
230     */
231     void addSlideEndHandler( const EventHandlerSharedPtr& rHandler );
232     void removeSlideEndHandler( const EventHandlerSharedPtr& rHandler );
233 
234     /** Register an event handler that will be called when an
235         XAnimationNode starts its active duration.
236 
237         Note that <em>all</em> registered handlers will be called
238         when the animation start occurs. This is in contrast to
239         the mouse events below.
240 
241         @param rHandler
242         Handler to call when the animation start
243     */
244     void addAnimationStartHandler(
245         const AnimationEventHandlerSharedPtr& rHandler );
246     void removeAnimationStartHandler(
247         const AnimationEventHandlerSharedPtr& rHandler );
248 
249     /** Register an event handler that will be called when an
250         XAnimationNode ends its active duration.
251 
252         Note that <em>all</em> registered handlers will be called
253         when the animation end occurs. This is in contrast to
254         the mouse events below.
255 
256         @param rHandler
257         Handler to call when the animation ends
258     */
259     void addAnimationEndHandler(
260         const AnimationEventHandlerSharedPtr& rHandler );
261     void removeAnimationEndHandler(
262         const AnimationEventHandlerSharedPtr& rHandler );
263 
264     /** Register an event handler that will be called when the
265         main animation sequence of a slide ends its active
266         duration.
267 
268         Note that <em>all</em> registered handlers will be
269         called when the animation end occurs. This is in
270         contrast to the mouse events below.
271 
272         @param rHandler
273         Handler to call when the animation ends
274     */
275     void addSlideAnimationsEndHandler(
276         const EventHandlerSharedPtr& rHandler );
277     void removeSlideAnimationsEndHandler(
278         const EventHandlerSharedPtr& rHandler );
279 
280     /** Register an event handler that will be called when an
281         XAudio node's sound stops playing.
282 
283         Note that <em>all</em> registered handlers will be
284         called when the audio stops. This is in contrast to
285         the mouse events below.
286 
287         @param rHandler
288         Handler to call when the audio stops
289     */
290     void addAudioStoppedHandler(
291         const AnimationEventHandlerSharedPtr& rHandler );
292     void removeAudioStoppedHandler(
293         const AnimationEventHandlerSharedPtr& rHandler );
294 
295     /** Register an event handler that will be called when an
296         XCommand node's with the command STOPAUDIO is activated.
297 
298         Note that <em>all</em> registered handlers will be
299         called when the audio stops. This is in contrast to
300         the mouse events below.
301 
302         @param rHandler
303         Handler to call when command is activated
304     */
305     void addCommandStopAudioHandler(
306         const AnimationEventHandlerSharedPtr& rHandler );
307     void removeCommandStopAudioHandler(
308         const AnimationEventHandlerSharedPtr& rHandler );
309 
310     /** Register a handler that is called when the show enters
311         or exits pause mode.
312     */
313     void addPauseHandler( const PauseEventHandlerSharedPtr& rHandler );
314     void removePauseHandler( const PauseEventHandlerSharedPtr& rHandler );
315 
316     /** Register a mouse handler that is called on mouse click
317 
318         For every mouse click, only one of the handlers
319         registered here is called. The handlers are considered
320         with decreasing priority, i.e. the handler with the
321         currently highest priority will be called.
322 
323         Since the handlers can reject down and up events
324         individually, handlers should expect to be called with
325         non-matching down and up-press counts. If your handler
326         cannot cope with that, it must have the highest
327         priority of all added handlers.
328     */
329     void addClickHandler( const MouseEventHandlerSharedPtr& rHandler,
330                           double                            nPriority );
331     void removeClickHandler( const MouseEventHandlerSharedPtr& rHandler );
332 
333     /** Register a mouse handler that is called on a double
334         mouse click
335 
336         For every mouse double click, only one of the handlers
337         registered here is called. The handlers are considered
338         with decreasing priority, i.e. the handler with the
339         currently highest priority will be called.
340 
341         Since the handlers can reject down and up events
342         individually, handlers should expect to be called with
343         non-matching down and up-press counts. If your handler
344         cannot cope with that, it must have the highest
345         priority of all added handlers.
346     */
347     void addDoubleClickHandler( const MouseEventHandlerSharedPtr&   rHandler,
348                                 double                              nPriority );
349     void removeDoubleClickHandler( const MouseEventHandlerSharedPtr& rHandler );
350 
351     /** Register a mouse handler that is called for mouse moves.
352 
353         For every mouse move, only one of the handlers
354         registered here is called. The handlers are considered
355         with decreasing priority, i.e. the handler with the
356         currently highest priority will be called.
357     */
358     void addMouseMoveHandler( const MouseEventHandlerSharedPtr& rHandler,
359                               double                            nPriority );
360     void removeMouseMoveHandler( const MouseEventHandlerSharedPtr& rHandler );
361 
362 
363     /** Registers a hyperlink click handler.
364 
365         For every hyperlink click, only one of the handlers registered
366         here is called. The handlers are considered with decreasing
367         priority, i.e. the handler with the currently highest priority
368         will be called.
369 
370         @param rHandler
371         @param nPriority
372     */
373     void addHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler,
374                               double                           nPriority );
375     void removeHyperlinkHandler( const HyperlinkHandlerSharedPtr& rHandler );
376 
377 
378     // External event notifications
379     // =========================================================
380 
381     /** View added.
382 
383         This method adds another view, which the show is
384         displayed on. On every added view, the EventMultiplexer
385         registers mouse and motion event listeners.
386     */
387     bool notifyViewAdded( const UnoViewSharedPtr& rView );
388 
389     /** View removed
390 
391         This method removes a view. Registered mouse and
392         motion event listeners are revoked.
393     */
394     bool notifyViewRemoved( const UnoViewSharedPtr& rView );
395 
396     /** View changed
397 
398         This method announces a changed view to all view
399         listeners. View changes include size and transformation.
400 
401         @param rView
402         View that has changed
403     */
404     bool notifyViewChanged( const UnoViewSharedPtr& rView );
405 
406     /** View changed
407 
408         This method announces a changed view to all view
409         listeners. View changes include size and transformation.
410 
411         @param xView
412         View that has changed
413     */
414     bool notifyViewChanged( const ::com::sun::star::uno::Reference<
415                                ::com::sun::star::presentation::XSlideShowView>& xView );
416 
417     /** All Views changed
418 
419         This method announces to all view listeners that
420         <em>every</em> known view has changed. View changes include
421         size and transformation.
422     */
423     bool notifyViewsChanged();
424 
425     /** View clobbered
426 
427         This method announces that the given view has been clobbered
428         by something external to the slideshow, and needs an update.
429 
430         @param xView
431         View that has been clobbered
432     */
433     bool notifyViewClobbered( const ::com::sun::star::uno::Reference<
434                                  ::com::sun::star::presentation::XSlideShowView>& xView );
435 
436     /** New shape event listener added
437 
438         This method announces that the given listener was added for
439         the specified shape.
440 
441         @return true, if at least one handler successfully processed
442         the notification.
443      */
444     bool notifyShapeListenerAdded( const ::com::sun::star::uno::Reference<
445                                       ::com::sun::star::presentation::XShapeEventListener>& xListener,
446                                    const ::com::sun::star::uno::Reference<
447                                       ::com::sun::star::drawing::XShape>&                   xShape );
448 
449     /** A shape event listener was removed
450 
451         This method announces that the given listener was removed for
452         the specified shape.
453 
454         @return true, if at least one handler successfully processed
455         the notification.
456      */
457     bool notifyShapeListenerRemoved( const ::com::sun::star::uno::Reference<
458                                          ::com::sun::star::presentation::XShapeEventListener>& xListener,
459                                      const ::com::sun::star::uno::Reference<
460                                          ::com::sun::star::drawing::XShape>&                   xShape );
461 
462     /** A new shape cursor was set
463 
464         This method announces that the given cursor was set for the
465         specified shape.
466 
467         @return true, if at least one handler successfully processed
468         the notification.
469      */
470     bool notifyShapeCursorChange( const ::com::sun::star::uno::Reference<
471                                      ::com::sun::star::drawing::XShape>&  xShape,
472                                   sal_Int16                               nPointerShape );
473 
474     /** Notify a new user paint color
475 
476         Sending this notification also implies that user paint is
477         enabled. User paint denotes the feature to draw colored lines
478         on top of the slide content.
479 
480         @return true, if this event was processed by
481         anybody. If false is returned, no handler processed
482         this event (and probably, nothing will happen at all)
483     */
484     bool notifyUserPaintColor( RGBColor const& rUserColor );
485 
486     /** Notify a new user paint width
487 
488          Sending this notification also implies that user paint is
489          enabled. .
490 
491          @return true, if this event was processed by
492          anybody. If false is returned, no handler processed
493          this event (and probably, nothing will happen at all)
494          */
495     bool notifyUserPaintStrokeWidth( double rUserStrokeWidth );
496 
497 
498 	/** Notify a new user paint erase all ink mode
499 
500 	 Sending this notification also implies that user paint is
501 	 enabled. User paint denotes the feature to draw colored lines
502 	 on top of the slide content.
503 
504 	 @return true, if this event was processed by
505 	 anybody. If false is returned, no handler processed
506 	 this event (and probably, nothing will happen at all)
507 	 */
508 	bool notifyEraseAllInk( bool const& rEraseAllInk );
509 	bool notifySwitchPenMode();
510 	bool notifySwitchEraserMode();
511 	bool notifyEraseInkWidth( sal_Int32 rEraseInkSize );
512 
513     /** Notify that user paint is disabled
514 
515         User paint denotes the feature to draw colored lines on top of
516         the slide content.
517 
518         @return true, if this event was processed by
519         anybody. If false is returned, no handler processed
520         this event (and probably, nothing will happen at all)
521     */
522     bool notifyUserPaintDisabled();
523 
524     /** Notify that the user requested the next effect.
525 
526         This requests the slideshow to display the next
527         effect, or move to the next slide, if none are left.
528 
529         @return true, if this event was processed by
530         anybody. If false is returned, no handler processed
531         this event (and probably, nothing will happen at all)
532     */
533     bool notifyNextEffect();
534 
535     /** Notify that a new slide is about to be displayed
536     */
537 	bool notifySlideTransitionStarted();
538 
539     /** Notify that a new slide has started
540 
541         This method is to be used from the Presentation object
542         to signal that a new slide is starting now. This will
543         invoke all registered slide start handlers.
544 
545         @return true, if this event was processed by
546         anybody. If false is returned, no handler processed
547         this event (and probably, nothing will happen at all)
548     */
549     bool notifySlideStartEvent();
550 
551     /** Notify that a slide has ended
552 
553         This method is to be used from the Presentation object
554         to signal that a slide is ending now. This will invoke
555         all registered slide end handlers.
556 
557         @return true, if this event was processed by
558         anybody. If false is returned, no handler processed
559         this event (and probably, nothing will happen at all)
560     */
561     bool notifySlideEndEvent();
562 
563     /** Notify that the given node enters its active duration.
564 
565         This method is to be used from the AnimationNode
566         objects to signal that the active duration
567         begins. This will invoke all registered animation
568         start handlers.
569 
570         @param rNode
571         Node which enters active duration.
572 
573         @return true, if this event was processed by
574         anybody. If false is returned, no handler processed
575         this event (and probably, nothing will happen at all)
576     */
577     bool notifyAnimationStart( const boost::shared_ptr<AnimationNode>& rNode );
578 
579     /** Notify that the given node leaves its active duration.
580 
581         This method is to be used from the AnimationNode
582         objects to signal that the active duration
583         ends now. This will invoke all registered animation
584         end handlers.
585 
586         @param rNode
587         Node which leaves active duration.
588 
589         @return true, if this event was processed by
590         anybody. If false is returned, no handler processed
591         this event (and probably, nothing will happen at all)
592     */
593     bool notifyAnimationEnd( const boost::shared_ptr<AnimationNode>& rNode );
594 
595     /** Notify that the slide animations sequence leaves its
596         active duration.
597 
598         @return true, if this event was processed by
599         anybody. If false is returned, no handler processed
600         this event (and probably, nothing will happen at all)
601     */
602     bool notifySlideAnimationsEnd();
603 
604     /** Notify that for the given node, audio output has stopped.
605 
606         This method is to be used from the AnimationNode
607         objects to signal that audio playback has just
608         stopped.  This will invoke all registered audio
609         stopped andlers.
610 
611         @param rNode
612         Node for which audio has stopped.
613 
614         @return true, if this event was processed by
615         anybody. If false is returned, no handler processed
616         this event (and probably, nothing will happen at all)
617     */
618     bool notifyAudioStopped( const boost::shared_ptr<AnimationNode>& rNode );
619 
620     /** Notify that the show has entered or exited pause mode
621 
622         This method is to be used from the Presentation object
623         to signal that a slide is entering (bPauseShow=true)
624         or exiting (bPauseShow=false) pause mode. This will
625         invoke all registered slide end handlers.
626 
627         @return true, if this event was processed by
628         anybody. If false is returned, no handler processed
629         this event (and probably, nothing will happen at all)
630     */
631     bool notifyPauseMode( bool bPauseShow );
632 
633     /** Notify that all audio has to be stoped.
634 
635         This method is used by XCommand nodes and all sound
636         playing nodes should listen for this command and
637         stop theire sounds when its fired.
638 
639         @return true, if this event was processed by
640         anybody. If false is returned, no handler processed
641         this event (and probably, nothing will happen at all)
642     */
643     bool notifyCommandStopAudio( const boost::shared_ptr<AnimationNode>& rNode );
644 
645     /** Botifies that a hyperlink has been clicked.
646 
647         @return true, if this event was processed by
648         anybody. If false is returned, no handler processed
649         this event (and probably, nothing will happen at all)
650     */
651     bool notifyHyperlinkClicked( ::rtl::OUString const& hyperLink );
652 
653 private:
654     boost::scoped_ptr<EventMultiplexerImpl> mpImpl;
655 };
656 
657 } // namespace internal
658 } // namespace Presentation
659 
660 #endif /* INCLUDED_SLIDESHOW_EVENTMULTIPLEXER_HXX */
661 
662