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