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 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_slideshow.hxx"
30 
31 // must be first
32 #include <canvas/debug.hxx>
33 #include <tools/diagnose_ex.h>
34 #include <canvas/verbosetrace.hxx>
35 
36 #include <com/sun/star/drawing/XShape.hpp>
37 #include <com/sun/star/animations/XAnimationNode.hpp>
38 #include <com/sun/star/animations/Timing.hpp>
39 #include <com/sun/star/animations/EventTrigger.hpp>
40 #include <com/sun/star/animations/Event.hpp>
41 
42 #include "shape.hxx"
43 #include "subsettableshapemanager.hxx"
44 #include "usereventqueue.hxx"
45 #include "slideshowcontext.hxx"
46 #include "delayevent.hxx"
47 
48 namespace slideshow {
49 namespace internal {
50 
51 using namespace com::sun::star;
52 
53 EventSharedPtr generateEvent(
54     uno::Any const& rEventDescription,
55     Delay::FunctorT const& rFunctor,
56     SlideShowContext const& rContext,
57     double nAdditionalDelay )
58 {
59     EventSharedPtr pEvent;
60 
61     if (! rEventDescription.hasValue())
62         return pEvent;
63 
64     animations::Timing eTiming;
65     animations::Event aEvent;
66     uno::Sequence<uno::Any> aSequence;
67     double nDelay1 = 0;
68 
69     if (rEventDescription >>= eTiming) {
70         switch (eTiming) {
71         case animations::Timing_INDEFINITE:
72             break; // don't schedule no event
73         case animations::Timing_MEDIA:
74             OSL_ENSURE( false, "MEDIA timing not yet implemented!" );
75             break;
76         default:
77             ENSURE_OR_THROW( false, "unexpected case!" );
78         }
79     }
80     else if (rEventDescription >>= aEvent) {
81 
82         // try to extract additional event delay
83         double nDelay2 = 0.0;
84         if (aEvent.Offset.hasValue() && !(aEvent.Offset >>= nDelay2)) {
85             OSL_ENSURE( false, "offset values apart from DOUBLE not "
86                         "recognized in animations::Event!" );
87         }
88 
89         // common vars used inside switch
90         uno::Reference<animations::XAnimationNode> xNode;
91         uno::Reference<drawing::XShape> xShape;
92         ShapeSharedPtr pShape;
93 
94         // TODO(F1): Respect aEvent.Repeat value
95 
96         switch (aEvent.Trigger) {
97         default:
98             ENSURE_OR_THROW( false, "unexpected event trigger!" );
99         case animations::EventTrigger::NONE:
100             // no event at all
101             break;
102         case animations::EventTrigger::ON_BEGIN:
103             OSL_ENSURE( false, "event trigger ON_BEGIN not yet implemented!" );
104             break;
105         case animations::EventTrigger::ON_END:
106             OSL_ENSURE( false, "event trigger ON_END not yet implemented!" );
107             break;
108         case animations::EventTrigger::BEGIN_EVENT:
109             // try to extract XAnimationNode event source
110             if (aEvent.Source >>= xNode) {
111                 pEvent = makeDelay( rFunctor,
112                                     nDelay2 + nAdditionalDelay,
113                                     "generateEvent, BEGIN_EVENT");
114                 rContext.mrUserEventQueue.registerAnimationStartEvent(
115                     pEvent, xNode );
116             }
117             else {
118                 OSL_ENSURE(false, "could not extract source XAnimationNode "
119                            "for BEGIN_EVENT!" );
120             }
121             break;
122         case animations::EventTrigger::END_EVENT:
123             // try to extract XAnimationNode event source
124             if (aEvent.Source >>= xNode) {
125                 pEvent = makeDelay( rFunctor,
126                                     nDelay2 + nAdditionalDelay,
127                                     "generateEvent, END_EVENT");
128                 rContext.mrUserEventQueue.registerAnimationEndEvent(
129                     pEvent, xNode );
130             }
131             else {
132                 OSL_ENSURE( false, "could not extract source XAnimationNode "
133                             "for END_EVENT!" );
134             }
135             break;
136         case animations::EventTrigger::ON_CLICK:
137             // try to extract XShape event source
138             if ((aEvent.Source >>= xShape) &&
139                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
140             {
141                 pEvent = makeDelay( rFunctor,
142                                     nDelay2 + nAdditionalDelay,
143                                     "generateEvent, ON_CLICK");
144                 rContext.mrUserEventQueue.registerShapeClickEvent(
145                     pEvent, pShape );
146             }
147             else {
148                 OSL_ENSURE( false, "could not extract source XAnimationNode "
149                             "for ON_CLICK!" );
150             }
151             break;
152         case animations::EventTrigger::ON_DBL_CLICK:
153             // try to extract XShape event source
154             if ((aEvent.Source >>= xShape) &&
155                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
156             {
157                 pEvent = makeDelay( rFunctor,
158                                     nDelay2 + nAdditionalDelay,
159                                     "generateEvent, ON_DBL_CLICK");
160                 rContext.mrUserEventQueue.registerShapeDoubleClickEvent(
161                     pEvent, pShape );
162             }
163             else {
164                 OSL_ENSURE( false, "could not extract source XAnimationNode "
165                             "for ON_DBL_CLICK!" );
166             }
167             break;
168         case animations::EventTrigger::ON_MOUSE_ENTER:
169             // try to extract XShape event source
170             if ((aEvent.Source >>= xShape) &&
171                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
172             {
173                 pEvent = makeDelay( rFunctor,
174                                     nDelay2 + nAdditionalDelay,
175                                     "generateEvent, ON_MOUSE_ENTER");
176                 rContext.mrUserEventQueue.registerMouseEnterEvent(
177                     pEvent, pShape );
178             }
179             else {
180                 OSL_ENSURE( false, "could not extract source XAnimationNode "
181                             "for ON_MOUSE_ENTER!" );
182             }
183             break;
184         case animations::EventTrigger::ON_MOUSE_LEAVE:
185             // try to extract XShape event source
186             if ((aEvent.Source >>= xShape) &&
187                 (pShape = rContext.mpSubsettableShapeManager->lookupShape(xShape)).get())
188             {
189                 pEvent = makeDelay( rFunctor,
190                                     nDelay2 + nAdditionalDelay,
191                                     "generateEvent, ON_MOUSE_LEAVE");
192                 rContext.mrUserEventQueue.registerMouseLeaveEvent(
193                     pEvent, pShape );
194             }
195             else {
196                 OSL_ENSURE( false, "could not extract source XAnimationNode "
197                             "for ON_MOUSE_LEAVE!" );
198             }
199             break;
200         case animations::EventTrigger::ON_PREV:
201             OSL_ENSURE( false, "event trigger ON_PREV not yet implemented, "
202                         "mapped to ON_NEXT!" );
203             // FALLTHROUGH intended
204         case animations::EventTrigger::ON_NEXT:
205             pEvent = makeDelay( rFunctor,
206                                 nDelay2 + nAdditionalDelay,
207                                 "generateEvent, ON_NEXT");
208             rContext.mrUserEventQueue.registerNextEffectEvent( pEvent );
209             break;
210         case animations::EventTrigger::ON_STOP_AUDIO:
211             // try to extract XAnimationNode event source
212             if (aEvent.Source >>= xNode) {
213                 pEvent = makeDelay( rFunctor,
214                                     nDelay2 + nAdditionalDelay,
215                                     "generateEvent, ON_STOP_AUDIO");
216                 rContext.mrUserEventQueue.registerAudioStoppedEvent(
217                     pEvent, xNode );
218             }
219             else {
220                 OSL_ENSURE( false, "could not extract source XAnimationNode "
221                             "for ON_STOP_AUDIO!" );
222             }
223             break;
224         case animations::EventTrigger::REPEAT:
225             OSL_ENSURE( false, "event trigger REPEAT not yet implemented!" );
226             break;
227         }
228     }
229     else if (rEventDescription >>= aSequence) {
230         OSL_ENSURE( false, "sequence of timing primitives "
231                     "not yet implemented!" );
232     }
233     else if (rEventDescription >>= nDelay1) {
234         pEvent = makeDelay( rFunctor,
235                             nDelay1 + nAdditionalDelay,
236                             "generateEvent with delay");
237         // schedule delay event
238         rContext.mrEventQueue.addEvent( pEvent );
239     }
240 
241     return pEvent;
242 }
243 
244 } // namespace internal
245 } // namespace slideshow
246 
247